Skip to content

Commit

Permalink
- introduce new configuration to enable checksum validation only for …
Browse files Browse the repository at this point in the history
…detected versions

  - version is detected from `gradle-wrapper.properties`
  - checksum is only fetched for these particular versions
- FIX gradle#96

While not specifically targeted, this also
- RESOLVES https://github.com/gradle/wrapper-validation-action/issues/142

May enable https://github.com/gradle/wrapper-validation-action/issues/35
  • Loading branch information
mikepenz authored Jan 25, 2024
1 parent 342dbeb commit 1f0a388
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 5 deletions.
8 changes: 6 additions & 2 deletions src/checksums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ const httpc = new httpm.HttpClient(
)

export async function fetchValidChecksums(
allowSnapshots: boolean
allowSnapshots: boolean,
detectVersions: boolean,
detectedVersions: string[]
): Promise<string[]> {
const all = await httpGetJsonArray('https://services.gradle.org/versions/all')
const withChecksum = all.filter(
Expand All @@ -18,7 +20,9 @@ export async function fetchValidChecksums(
)
const allowed = withChecksum.filter(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(entry: any) => allowSnapshots || !entry.snapshot
(entry: any) =>
(allowSnapshots || !entry.snapshot) &&
(!detectVersions || detectedVersions.includes(entry.version))
)
const checksumUrls = allowed.map(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
61 changes: 61 additions & 0 deletions src/find.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import * as util from 'util'
import * as path from 'path'
import * as fs from 'fs'
import * as readline from 'readline'
import unhomoglyph from 'unhomoglyph'
import events from 'events'
import * as core from '@actions/core'

const readdir = util.promisify(fs.readdir)
const versionRegex = new RegExp(/\/gradle-(.+)-/)

export async function findWrapperJars(baseDir: string): Promise<string[]> {
const files = await recursivelyListFiles(baseDir)
Expand All @@ -13,6 +17,63 @@ export async function findWrapperJars(baseDir: string): Promise<string[]> {
.sort((a, b) => a.localeCompare(b))
}

export async function detectVersions(wrapperJars: string[]): Promise<string[]> {
return (
await Promise.all(
wrapperJars.map(async wrapperJar => await findWrapperVersion(wrapperJar))
)
).filter(version => version !== undefined) as string[]
}

async function findWrapperVersion(
wrapperJar: string
): Promise<string | undefined> {
const jar = path.parse(wrapperJar)
const properties = path.resolve(jar.dir, 'gradle-wrapper.properties')

if (fs.existsSync(properties)) {
try {
const lineReader = readline.createInterface({
input: fs.createReadStream(properties)
})

let distributionUrl = ''
lineReader.on('line', function (line) {
if (line.startsWith('distributionUrl=')) {
distributionUrl = line
lineReader.close()
}
})

await events.once(lineReader, 'close')

if (distributionUrl) {
const matchedVersion = distributionUrl.match(versionRegex)
if (matchedVersion && matchedVersion.length >= 1) {
return matchedVersion[1]
} else {
core.debug(
`Could not parse version from distributionUrl in gradle-wrapper.properties file: ${properties}`
)
}
} else {
core.debug(
`Could not identify valid distributionUrl in gradle-wrapper.properties file: ${properties}`
)
}
} catch (error) {
core.warning(
`Failed to retrieve version from gradle-wrapper.properties file: ${properties} due to ${error}`
)
}
} else {
core.debug(
`No gradle-wrapper.properties file existed alongside ${wrapperJar}`
)
}
return undefined
}

async function recursivelyListFiles(baseDir: string): Promise<string[]> {
const childrenNames = await readdir(baseDir)
const childrenPaths = await Promise.all(
Expand Down
3 changes: 2 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export async function run(): Promise<void> {
path.resolve('.'),
+core.getInput('min-wrapper-count'),
core.getInput('allow-snapshots') === 'true',
core.getInput('allow-checksums').split(',')
core.getInput('allow-checksums').split(','),
core.getInput('detect-version') === 'true'
)
if (result.isValid()) {
core.info(result.toDisplayString())
Expand Down
15 changes: 13 additions & 2 deletions src/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ export async function findInvalidWrapperJars(
gitRepoRoot: string,
minWrapperCount: number,
allowSnapshots: boolean,
allowChecksums: string[]
allowChecksums: string[],
detectVersions: boolean
): Promise<ValidationResult> {
const wrapperJars = await find.findWrapperJars(gitRepoRoot)
const result = new ValidationResult([], [])
Expand All @@ -16,7 +17,17 @@ export async function findInvalidWrapperJars(
)
}
if (wrapperJars.length > 0) {
const validChecksums = await checksums.fetchValidChecksums(allowSnapshots)
let detectedVersions: string[]
if (detectVersions) {
detectedVersions = await find.detectVersions(wrapperJars)
} else {
detectedVersions = []
}
const validChecksums = await checksums.fetchValidChecksums(
allowSnapshots,
detectVersions,
detectedVersions
)
validChecksums.push(...allowChecksums)
for (const wrapperJar of wrapperJars) {
const sha = await hash.sha256File(wrapperJar)
Expand Down

0 comments on commit 1f0a388

Please sign in to comment.