forked from github/docs
-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Content Linter Rule] Third Party Action References Must Use SHA (#52…
…282) Co-authored-by: Rachael Sewell <[email protected]> Co-authored-by: Ben Ahmady <[email protected]> Co-authored-by: Felicity Chapman <[email protected]>
- Loading branch information
1 parent
72faf23
commit 7c49068
Showing
18 changed files
with
231 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
src/content-linter/lib/linting-rules/third-party-action-pinning.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import yaml from 'js-yaml' | ||
import { addError, filterTokens } from 'markdownlint-rule-helpers' | ||
|
||
import { liquid } from '#src/content-render/index.js' | ||
import { allVersions } from '#src/versions/lib/all-versions.js' | ||
|
||
// Detects third-party actions in the format `owner/repo@ref` | ||
const actionRegex = /[\w-]+\/[\w-]+@[\w-]+/ | ||
// Detects a full-length commit SHA (40 hexadecimal characters) | ||
const shaRegex = /[\w-]+\/[\w-]+@[0-9a-fA-F]{40}/ | ||
// Detects first-party actions | ||
const firstPartyPrefixes = ['actions/', 'github/', 'octo-org/', 'OWNER/'] | ||
|
||
export const thirdPartyActionPinning = { | ||
names: ['GHD041', 'third-party-action-pinning'], | ||
description: | ||
'Code examples that use third-party actions must always pin to a full length commit SHA', | ||
tags: ['feature', 'actions'], | ||
parser: 'markdownit', | ||
asynchronous: true, | ||
function: (params, onError) => { | ||
filterTokens(params, 'fence', async (token) => { | ||
const lang = token.info.trim().split(/\s+/u).shift().toLowerCase() | ||
if (lang !== 'yaml' && lang !== 'yml') return | ||
if (!token.content.includes('steps:')) return | ||
if (!token.content.includes('uses:')) return | ||
|
||
const context = { | ||
currentLanguage: 'en', | ||
currentVersionObj: allVersions['free-pro-team@latest'], | ||
} | ||
// If we don't parse the Liquid first, yaml loading chokes on {% raw %} tags | ||
const renderedYaml = await liquid.parseAndRender(token.content, context) | ||
try { | ||
const yamlObj = yaml.load(renderedYaml) | ||
const steps = getWorkflowSteps(yamlObj) | ||
if (!steps.some((step) => step.uses)) return | ||
|
||
steps.forEach((step) => { | ||
if (step.uses) { | ||
const actionMatch = step.uses.match(actionRegex) | ||
if (actionMatch) { | ||
const isFirstParty = firstPartyPrefixes.some((prefix) => step.uses.startsWith(prefix)) | ||
if (!isFirstParty && !shaRegex.test(step.uses)) { | ||
addError( | ||
onError, | ||
getLineNumber(token.content, step.uses) + token.lineNumber, | ||
'Code examples that use third-party actions must always pin to a full length commit SHA', | ||
step.uses, | ||
) | ||
} | ||
} | ||
} | ||
}) | ||
} catch (e) { | ||
if (e instanceof yaml.YAMLException) { | ||
console.log('YAML Exception file:', params.name) | ||
console.error('YAML Exception:', e.message) | ||
} else { | ||
console.error('Error parsing YAML:', e) | ||
} | ||
} | ||
}) | ||
}, | ||
} | ||
|
||
function getWorkflowSteps(yamlObj) { | ||
if (yamlObj?.jobs) { | ||
const jobs = Object.values(yamlObj.jobs) | ||
return jobs.flatMap((job) => job.steps || []) | ||
} else if (yamlObj?.steps) { | ||
return yamlObj.steps | ||
} | ||
return [] | ||
} | ||
|
||
function getLineNumber(tokenContent, step) { | ||
const contentLines = tokenContent.split('\n') | ||
return contentLines.findIndex((line) => line.includes(step)) + 1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.