Adjust printWidth to 120.

This commit is contained in:
Fabio Niephaus
2025-02-10 09:16:33 +01:00
committed by Fabio Niephaus
parent 93a3b57d30
commit 9b77b7e1c6
33 changed files with 373 additions and 957 deletions

View File

@@ -26,7 +26,7 @@
* @fileoverview this file provides methods handling dependency cache
*/
import {join} from 'path'
import { join } from 'path'
import os from 'os'
import * as cache from '@actions/cache'
import * as core from '@actions/core'
@@ -53,17 +53,9 @@ const supportedPackageManager: PackageManager[] = [
},
{
id: 'gradle',
path: [
join(os.homedir(), '.gradle', 'caches'),
join(os.homedir(), '.gradle', 'wrapper')
],
path: [join(os.homedir(), '.gradle', 'caches'), join(os.homedir(), '.gradle', 'wrapper')],
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle
pattern: [
'**/*.gradle*',
'**/gradle-wrapper.properties',
'buildSrc/**/Versions.kt',
'buildSrc/**/Dependencies.kt'
]
pattern: ['**/*.gradle*', '**/gradle-wrapper.properties', 'buildSrc/**/Versions.kt', 'buildSrc/**/Dependencies.kt']
},
{
id: 'sbt',
@@ -76,23 +68,18 @@ const supportedPackageManager: PackageManager[] = [
`!${join(os.homedir(), '.sbt', '*.lock')}`,
`!${join(os.homedir(), '**', 'ivydata-*.properties')}`
],
pattern: [
'**/*.sbt',
'**/project/build.properties',
'**/project/**.{scala,sbt}'
]
pattern: ['**/*.sbt', '**/project/build.properties', '**/project/**.{scala,sbt}']
}
]
function getCoursierCachePath(): string {
if (os.type() === 'Linux') return join(os.homedir(), '.cache', 'coursier')
if (os.type() === 'Darwin')
return join(os.homedir(), 'Library', 'Caches', 'Coursier')
if (os.type() === 'Darwin') return join(os.homedir(), 'Library', 'Caches', 'Coursier')
return join(os.homedir(), 'AppData', 'Local', 'Coursier', 'Cache')
}
function findPackageManager(id: string): PackageManager {
const packageManager = supportedPackageManager.find(pm => pm.id === id)
const packageManager = supportedPackageManager.find((pm) => pm.id === id)
if (packageManager === undefined) {
throw new Error(`unknown package manager specified: ${id}`)
}
@@ -105,9 +92,7 @@ function findPackageManager(id: string): PackageManager {
* If there is no file matched to {@link PackageManager.path}, the generated key ends with a dash (-).
* @see {@link https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows#matching-a-cache-key|spec of cache key}
*/
async function computeCacheKey(
packageManager: PackageManager
): Promise<string> {
async function computeCacheKey(packageManager: PackageManager): Promise<string> {
const hash = await glob.hashFiles(packageManager.pattern.join('\n'))
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${packageManager.id}-${hash}`
}
@@ -158,9 +143,7 @@ export async function save(id: string): Promise<void> {
return
} else if (matchedKey === primaryKey) {
// no change in target directories
core.info(
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
)
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`)
return
}
try {
@@ -190,14 +173,8 @@ export async function save(id: string): Promise<void> {
* @returns true if the given error seems related to the {@link https://github.com/actions/cache/issues/454|running Gradle Daemon issue}.
* @see {@link https://github.com/actions/cache/issues/454#issuecomment-840493935|why --no-daemon is necessary}
*/
function isProbablyGradleDaemonProblem(
packageManager: PackageManager,
error: Error
): boolean {
if (
packageManager.id !== 'gradle' ||
process.env['RUNNER_OS'] !== 'Windows'
) {
function isProbablyGradleDaemonProblem(packageManager: PackageManager, error: Error): boolean {
if (packageManager.id !== 'gradle' || process.env['RUNNER_OS'] !== 'Windows') {
return false
}
const message = error.message || ''

View File

@@ -1,19 +1,13 @@
import * as core from '@actions/core'
export function checkForUpdates(
graalVMVersion: string,
javaVersion: string
): void {
export function checkForUpdates(graalVMVersion: string, javaVersion: string): void {
if (javaVersion === '20') {
core.notice(
'A new GraalVM release is available! Please consider upgrading to GraalVM for JDK 21: https://medium.com/graalvm/graalvm-for-jdk-21-is-here-ee01177dd12d'
)
return
}
if (
graalVMVersion.length > 0 &&
(javaVersion === '17' || javaVersion === '19')
) {
if (graalVMVersion.length > 0 && (javaVersion === '17' || javaVersion === '19')) {
const recommendedJDK = javaVersion === '17' ? '17' : '21'
core.notice(
`A new GraalVM release is available! Please consider upgrading to GraalVM for JDK ${recommendedJDK}. Instructions: https://github.com/graalvm/setup-graalvm#migrating-from-graalvm-223-or-earlier-to-the-new-graalvm-for-jdk-17-and-later`

View File

@@ -1,8 +1,8 @@
import * as c from '../constants.js'
import * as core from '@actions/core'
import * as tc from '@actions/tool-cache'
import {exec} from '../utils.js'
import {join} from 'path'
import { exec } from '../utils.js'
import { join } from 'path'
const MUSL_NAME = 'x86_64-linux-musl-native'
const MUSL_VERSION = '10.2.1'
@@ -24,9 +24,7 @@ export async function setUpNativeImageMusl(): Promise<void> {
const muslPath = join(muslExtractPath, MUSL_NAME)
const zlibCommit = 'ec3df00224d4b396e2ac6586ab5d25f673caa4c2'
const zlibDownloadPath = await tc.downloadTool(
`https://github.com/madler/zlib/archive/${zlibCommit}.tar.gz`
)
const zlibDownloadPath = await tc.downloadTool(`https://github.com/madler/zlib/archive/${zlibCommit}.tar.gz`)
const zlibExtractPath = await tc.extractTar(zlibDownloadPath)
const zlibPath = join(zlibExtractPath, `zlib-${zlibCommit}`)
const zlibBuildOptions = {
@@ -36,13 +34,9 @@ export async function setUpNativeImageMusl(): Promise<void> {
CC: join(muslPath, 'bin', 'gcc')
}
}
await exec(
'./configure',
[`--prefix=${muslPath}`, '--static'],
zlibBuildOptions
)
await exec('./configure', [`--prefix=${muslPath}`, '--static'], zlibBuildOptions)
await exec('make', [], zlibBuildOptions)
await exec('make', ['install'], {cwd: zlibPath})
await exec('make', ['install'], { cwd: zlibPath })
core.info(`Adding ${MUSL_NAME} ${MUSL_VERSION} to tool-cache ...`)
toolPath = await tc.cacheDir(muslPath, MUSL_NAME, MUSL_VERSION)

View File

@@ -17,8 +17,7 @@ const BUILD_OUTPUT_JSON_PATH = tmpfile('native-image-build-output.json')
const BYTES_TO_KiB = 1024
const BYTES_TO_MiB = 1024 * 1024
const BYTES_TO_GiB = 1024 * 1024 * 1024
const DOCS_BASE =
'https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md'
const DOCS_BASE = 'https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md'
const INPUT_NI_JOB_REPORTS = 'native-image-job-reports'
const INPUT_NI_PR_REPORTS = 'native-image-pr-reports'
const INPUT_NI_PR_REPORTS_UPDATE = 'native-image-pr-reports-update-existing'
@@ -105,18 +104,14 @@ export async function setUpNativeImageBuildReports(
isGraalVMforJDK17OrLater ||
graalVMVersion === c.VERSION_LATEST ||
graalVMVersion === c.VERSION_DEV ||
(!graalVMVersion.startsWith(c.MANDREL_NAMESPACE) &&
semver.gte(toSemVer(graalVMVersion), '22.2.0'))
(!graalVMVersion.startsWith(c.MANDREL_NAMESPACE) && semver.gte(toSemVer(graalVMVersion), '22.2.0'))
if (!isSupported) {
core.warning(
`Build reports for PRs and job summaries are only available in GraalVM 22.2.0 or later. This build job uses GraalVM ${graalVMVersion}.`
)
return
}
setNativeImageOption(
javaVersionOrDev,
`-H:BuildOutputJSONFile=${BUILD_OUTPUT_JSON_PATH.replace(/\\/g, '\\\\')}`
) // Escape backslashes for Windows
setNativeImageOption(javaVersionOrDev, `-H:BuildOutputJSONFile=${BUILD_OUTPUT_JSON_PATH.replace(/\\/g, '\\\\')}`) // Escape backslashes for Windows
}
export async function generateReports(): Promise<void> {
@@ -127,9 +122,7 @@ export async function generateReports(): Promise<void> {
)
return
}
const buildOutput: BuildOutput = JSON.parse(
fs.readFileSync(BUILD_OUTPUT_JSON_PATH, 'utf8')
)
const buildOutput: BuildOutput = JSON.parse(fs.readFileSync(BUILD_OUTPUT_JSON_PATH, 'utf8'))
const report = createReport(buildOutput)
if (areJobReportsEnabled()) {
core.summary.addRaw(report)
@@ -144,9 +137,7 @@ export async function generateReports(): Promise<void> {
}
return createPRComment(report)
} else if (arePRReportsUpdateEnabled()) {
throw new Error(
`'${INPUT_NI_PR_REPORTS_UPDATE}' option requires '${INPUT_NI_PR_REPORTS}' to be set 'true'`
)
throw new Error(`'${INPUT_NI_PR_REPORTS_UPDATE}' option requires '${INPUT_NI_PR_REPORTS}' to be set 'true'`)
}
}
}
@@ -174,11 +165,7 @@ function createReport(data: BuildOutput): string {
objectCount = `${details.image_heap.objects.count.toLocaleString()} objects, `
}
const debugInfoBytes = details.debug_info ? details.debug_info.bytes : 0
const otherBytes =
details.total_bytes -
details.code_area.bytes -
details.image_heap.bytes -
debugInfoBytes
const otherBytes = details.total_bytes - details.code_area.bytes - details.image_heap.bytes - debugInfoBytes
let debugInfoLine = ''
if (details.debug_info) {
debugInfoLine = `
@@ -210,8 +197,7 @@ function createReport(data: BuildOutput): string {
let graalLine
if (info.graal_compiler) {
let pgoSuffix = ''
const isOracleGraalVM =
info.vendor_version && info.vendor_version.includes('Oracle GraalVM')
const isOracleGraalVM = info.vendor_version && info.vendor_version.includes('Oracle GraalVM')
if (isOracleGraalVM) {
const pgo = info.graal_compiler.pgo
const pgoText = pgo ? pgo.join('+') : 'off'
@@ -233,10 +219,7 @@ function createReport(data: BuildOutput): string {
let gcTotalTimeRatio = ''
if (resources.total_secs) {
totalTime = ` in ${secondsToHuman(resources.total_secs)}`
gcTotalTimeRatio = ` (${toPercent(
resources.garbage_collection.total_secs,
resources.total_secs
)} of total time)`
gcTotalTimeRatio = ` (${toPercent(resources.garbage_collection.total_secs, resources.total_secs)} of total time)`
}
return `${PR_COMMENT_TITLE}
@@ -278,56 +261,29 @@ function createReport(data: BuildOutput): string {
<tr>
<td align="left"><a href="${DOCS_BASE}#glossary-reachability" target="_blank">Reachable</a></td>
<td align="right">${analysisTypes.reachable.toLocaleString()}</td>
<td align="right">${toPercent(
analysisTypes.reachable,
analysisTypes.total
)}</td>
<td align="right">${toPercent(analysisTypes.reachable, analysisTypes.total)}</td>
<td align="right">${analysis.fields.reachable.toLocaleString()}</td>
<td align="right">${toPercent(
analysis.fields.reachable,
analysis.fields.total
)}</td>
<td align="right">${toPercent(analysis.fields.reachable, analysis.fields.total)}</td>
<td align="right">${analysis.methods.reachable.toLocaleString()}</td>
<td align="right">${toPercent(
analysis.methods.reachable,
analysis.methods.total
)}</td>
<td align="right">${toPercent(analysis.methods.reachable, analysis.methods.total)}</td>
</tr>
<tr>
<td align="left"><a href="${DOCS_BASE}#glossary-reflection-registrations" target="_blank">Reflection</a></td>
<td align="right">${analysisTypes.reflection.toLocaleString()}</td>
<td align="right">${toPercent(
analysisTypes.reflection,
analysisTypes.total
)}</td>
<td align="right">${toPercent(analysisTypes.reflection, analysisTypes.total)}</td>
<td align="right">${analysis.fields.reflection.toLocaleString()}</td>
<td align="right">${toPercent(
analysis.fields.reflection,
analysis.fields.total
)}</td>
<td align="right">${toPercent(analysis.fields.reflection, analysis.fields.total)}</td>
<td align="right">${analysis.methods.reflection.toLocaleString()}</td>
<td align="right">${toPercent(
analysis.methods.reflection,
analysis.methods.total
)}</td>
<td align="right">${toPercent(analysis.methods.reflection, analysis.methods.total)}</td>
</tr>
<tr>
<td align="left"><a href="${DOCS_BASE}#glossary-jni-access-registrations" target="_blank">JNI</a></td>
<td align="right">${analysisTypes.jni.toLocaleString()}</td>
<td align="right">${toPercent(
analysisTypes.jni,
analysisTypes.total
)}</td>
<td align="right">${toPercent(analysisTypes.jni, analysisTypes.total)}</td>
<td align="right">${analysis.fields.jni.toLocaleString()}</td>
<td align="right">${toPercent(
analysis.fields.jni,
analysis.fields.total
)}</td>
<td align="right">${toPercent(analysis.fields.jni, analysis.fields.total)}</td>
<td align="right">${analysis.methods.jni.toLocaleString()}</td>
<td align="right">${toPercent(
analysis.methods.jni,
analysis.methods.total
)}</td>
<td align="right">${toPercent(analysis.methods.jni, analysis.methods.total)}</td>
</tr>
<tr>
<td align="left"><a href="${DOCS_BASE}#glossary-reachability" target="_blank">Loaded</a></td>
@@ -356,19 +312,13 @@ function createReport(data: BuildOutput): string {
<tr>
<td align="left"><a href="${DOCS_BASE}#glossary-code-area" target="_blank">Code area</a></td>
<td align="right">${bytesToHuman(details.code_area.bytes)}</td>
<td align="right">${toPercent(
details.code_area.bytes,
details.total_bytes
)}</td>
<td align="right">${toPercent(details.code_area.bytes, details.total_bytes)}</td>
<td align="left">${details.code_area.compilation_units.toLocaleString()} compilation units</td>
</tr>
<tr>
<td align="left"><a href="${DOCS_BASE}#glossary-image-heap" target="_blank">Image heap</a></td>
<td align="right">${bytesToHuman(details.image_heap.bytes)}</td>
<td align="right">${toPercent(
details.image_heap.bytes,
details.total_bytes
)}</td>
<td align="right">${toPercent(details.image_heap.bytes, details.total_bytes)}</td>
<td align="left">${objectCount}${bytesToHuman(
details.image_heap.resources.bytes
)} for ${details.image_heap.resources.count.toLocaleString()} resources</td>
@@ -381,9 +331,7 @@ function createReport(data: BuildOutput): string {
</tr>
<tr>
<td align="left">Total</td>
<td align="right"><strong>${bytesToHuman(
details.total_bytes
)}</strong></td>
<td align="right"><strong>${bytesToHuman(details.total_bytes)}</strong></td>
<td align="right">100.000%</td>
<td align="left"></td>
</tr>
@@ -402,9 +350,7 @@ function createReport(data: BuildOutput): string {
</tr>
<tr>
<td align="left"><a href="${DOCS_BASE}#glossary-peak-rss" target="_blank">Peak RSS</a></td>
<td align="left">${bytesToHuman(
resources.memory.peak_rss_bytes
)} (${toPercent(
<td align="left">${bytesToHuman(resources.memory.peak_rss_bytes)} (${toPercent(
resources.memory.peak_rss_bytes,
resources.memory.system_total
)} of ${bytesToHuman(resources.memory.system_total)} system memory)</td>

View File

@@ -3,9 +3,9 @@ import * as core from '@actions/core'
import * as fs from 'fs'
import * as github from '@actions/github'
import * as glob from '@actions/glob'
import {basename} from 'path'
import { basename } from 'path'
import * as semver from 'semver'
import {setNativeImageOption} from '../utils.js'
import { setNativeImageOption } from '../utils.js'
const INPUT_NI_SBOM = 'native-image-enable-sbom'
const SBOM_FILE_SUFFIX = '.sbom.json'
@@ -67,10 +67,7 @@ interface DependencySnapshot {
>
}
export function setUpSBOMSupport(
javaVersionOrDev: string,
distribution: string
): void {
export function setUpSBOMSupport(javaVersionOrDev: string, distribution: string): void {
if (!isFeatureEnabled()) {
return
}
@@ -81,10 +78,7 @@ export function setUpSBOMSupport(
core.info('Enabled SBOM generation for Native Image build')
}
function validateJavaVersionAndDistribution(
javaVersionOrDev: string,
distribution: string
): void {
function validateJavaVersionAndDistribution(javaVersionOrDev: string, distribution: string): void {
if (distribution !== c.DISTRIBUTION_GRAALVM) {
throw new Error(
`The '${INPUT_NI_SBOM}' option is only supported for Oracle GraalVM (distribution '${c.DISTRIBUTION_GRAALVM}'), but found distribution '${distribution}'.`
@@ -92,9 +86,7 @@ function validateJavaVersionAndDistribution(
}
if (javaVersionOrDev === 'dev') {
throw new Error(
`The '${INPUT_NI_SBOM}' option is not supported for java-version 'dev'.`
)
throw new Error(`The '${INPUT_NI_SBOM}' option is not supported for java-version 'dev'.`)
}
if (javaVersionOrDev === 'latest-ea') {
@@ -142,15 +134,11 @@ async function findSBOMFilePath(): Promise<string> {
const sbomFiles = await globber.glob()
if (sbomFiles.length === 0) {
throw new Error(
'No SBOM found. Make sure native-image build completed successfully.'
)
throw new Error('No SBOM found. Make sure native-image build completed successfully.')
}
if (sbomFiles.length > 1) {
throw new Error(
`Expected one SBOM but found multiple: ${sbomFiles.join(', ')}.`
)
throw new Error(`Expected one SBOM but found multiple: ${sbomFiles.join(', ')}.`)
}
core.info(`Found SBOM: ${sbomFiles[0]}`)
@@ -162,9 +150,7 @@ function parseSBOM(jsonString: string): SBOM {
const sbomData: SBOM = JSON.parse(jsonString)
return sbomData
} catch (error) {
throw new Error(
`Failed to parse SBOM JSON: ${error instanceof Error ? error.message : String(error)}`
)
throw new Error(`Failed to parse SBOM JSON: ${error instanceof Error ? error.message : String(error)}`)
}
}
@@ -175,10 +161,7 @@ function mapToComponentsWithDependencies(sbom: SBOM): Component[] {
}
return sbom.components.map((component: Component) => {
const dependencies =
sbom.dependencies?.find(
(dep: Dependency) => dep.ref === component['bom-ref']
)?.dependsOn || []
const dependencies = sbom.dependencies?.find((dep: Dependency) => dep.ref === component['bom-ref'])?.dependsOn || []
return {
name: component.name,
@@ -201,17 +184,12 @@ function printSBOMContent(components: Component[]): void {
core.info('==================')
}
function convertSBOMToSnapshot(
sbomPath: string,
components: Component[]
): DependencySnapshot {
function convertSBOMToSnapshot(sbomPath: string, components: Component[]): DependencySnapshot {
const context = github.context
const sbomFileName = basename(sbomPath)
if (!sbomFileName.endsWith(SBOM_FILE_SUFFIX)) {
throw new Error(
`Invalid SBOM file name: ${sbomFileName}. Expected a file ending with ${SBOM_FILE_SUFFIX}.`
)
throw new Error(`Invalid SBOM file name: ${sbomFileName}. Expected a file ending with ${SBOM_FILE_SUFFIX}.`)
}
return {
@@ -244,18 +222,16 @@ function convertSBOMToSnapshot(
function mapComponentsToGithubAPIFormat(
components: Component[]
): Record<string, {package_url: string; dependencies?: string[]}> {
): Record<string, { package_url: string; dependencies?: string[] }> {
return Object.fromEntries(
components
.filter(component => {
.filter((component) => {
if (!component.purl) {
core.info(
`Component ${component.name} does not have a valid package URL (purl). Skipping.`
)
core.info(`Component ${component.name} does not have a valid package URL (purl). Skipping.`)
}
return component.purl
})
.map(component => [
.map((component) => [
component.name,
{
package_url: component.purl as string,
@@ -265,32 +241,27 @@ function mapComponentsToGithubAPIFormat(
)
}
async function submitDependencySnapshot(
snapshotData: DependencySnapshot
): Promise<void> {
const token = core.getInput(c.INPUT_GITHUB_TOKEN, {required: true})
async function submitDependencySnapshot(snapshotData: DependencySnapshot): Promise<void> {
const token = core.getInput(c.INPUT_GITHUB_TOKEN, { required: true })
const octokit = github.getOctokit(token)
const context = github.context
try {
await octokit.request(
'POST /repos/{owner}/{repo}/dependency-graph/snapshots',
{
owner: context.repo.owner,
repo: context.repo.repo,
version: snapshotData.version,
sha: snapshotData.sha,
ref: snapshotData.ref,
job: snapshotData.job,
detector: snapshotData.detector,
metadata: {},
scanned: snapshotData.scanned,
manifests: snapshotData.manifests,
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
await octokit.request('POST /repos/{owner}/{repo}/dependency-graph/snapshots', {
owner: context.repo.owner,
repo: context.repo.repo,
version: snapshotData.version,
sha: snapshotData.sha,
ref: snapshotData.ref,
job: snapshotData.job,
detector: snapshotData.detector,
metadata: {},
scanned: snapshotData.scanned,
manifests: snapshotData.manifests,
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
)
})
core.info('Dependency snapshot submitted successfully.')
} catch (error) {
throw new Error(