diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e15ab0dec1ca..0d8df1d9795a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -71,6 +71,7 @@ jobs: - release-notes - rest - search + - secret-scanning - shielding - tracking # - tests diff --git a/src/secret-scanning/README.md b/src/secret-scanning/README.md index c35a910cc505..431986c4bcaf 100644 --- a/src/secret-scanning/README.md +++ b/src/secret-scanning/README.md @@ -1,3 +1,18 @@ # Secret scanning -The files in the secret scanning folder support our secret scanning informational pages. +This secret scanning pipeline automates a table displayed on the [Supported secret scanning patterns](https://docs.github.com/code-security/secret-scanning/introduction/supported-secret-scanning-patterns#supported-secrets) page. + +Each day a workflow checks if the [data](src/secret-scanning/data/public-docs.yml) is up-to-date. When there are changes, the workflow automatically creates a pull request to update the `src/secret-scanning/data/public-docs.yml` file. The workflow runs `npm run sync-secret-scanning` to check for updates. + +This pipeline uses middleware to check if the path of the URL matches the page that contains the table. The middleware decorates the context with the data, which is displayed on the page using a Markdown table and Liquid. For example: + +```markdown + +{% ifversion fpt %} + +| Provider | Token | Partner | User | Push protection +|----|:----|:----:|:----:|:----:| +{%- for entry in secretScanningData %} +| {{ entry.provider }} | {{ entry.secretType }} | {% if entry.isPublic %}{% octicon "check" aria-label="Supported" %}{% else %}{% octicon "x" aria-label="Unsupported" %}{% endif %} | {% if entry.isPrivateWithGhas %}{% octicon "check" aria-label="Supported" %}{% else %}{% octicon "x" aria-label="Unsupported" %}{% endif %} | {% if entry.hasPushProtection %}{% octicon "check" aria-label="Supported" %}{% else %}{% octicon "x" aria-label="Unsupported" %}{% endif %} | +{%- endfor %} +``` diff --git a/src/secret-scanning/lib/config.json b/src/secret-scanning/lib/config.json index 95cbdb6c9783..9283b6a72e6e 100644 --- a/src/secret-scanning/lib/config.json +++ b/src/secret-scanning/lib/config.json @@ -1,4 +1,5 @@ { "sha": "bb86a15b48fe62030cf0ad8c38520508063ec20b", - "blob-sha": "96de8d829b93d371162f193a68ea19ae86ac0d09" + "blob-sha": "96de8d829b93d371162f193a68ea19ae86ac0d09", + "targetFilename": "code-security/secret-scanning/introduction/supported-secret-scanning-patterns" } \ No newline at end of file diff --git a/src/secret-scanning/middleware/secret-scanning.ts b/src/secret-scanning/middleware/secret-scanning.ts index 95eef0f48581..20b139194d21 100644 --- a/src/secret-scanning/middleware/secret-scanning.ts +++ b/src/secret-scanning/middleware/secret-scanning.ts @@ -9,17 +9,19 @@ import { ExtendedRequest, SecretScanningData } from '@/types' const secretScanningPath = 'src/secret-scanning/data/public-docs.yml' +// This is the path to the file that contains the secret scanning data. +// Currently it's: +// code-security/secret-scanning/introduction/supported-secret-scanning-pattern +const { targetFilename } = JSON.parse( + fs.readFileSync('src/secret-scanning/lib/config.json', 'utf-8'), +) + export default async function secretScanning( req: ExtendedRequest, res: Response, next: NextFunction, ) { - if ( - !req.pagePath!.endsWith( - 'code-security/secret-scanning/introduction/supported-secret-scanning-patterns', - ) - ) - return next() + if (!req.pagePath!.endsWith(targetFilename)) return next() const secretScanningData = yaml.load( fs.readFileSync(secretScanningPath, 'utf-8'), diff --git a/src/secret-scanning/tests/rendering.js b/src/secret-scanning/tests/rendering.js new file mode 100644 index 000000000000..1725a2fa5802 --- /dev/null +++ b/src/secret-scanning/tests/rendering.js @@ -0,0 +1,14 @@ +import { describe, expect, test } from 'vitest' +import { readFileSync } from 'fs' + +import { get } from '#src/tests/helpers/e2etest.js' + +describe('secret-scanning pipeline', () => { + const { targetFilename } = JSON.parse(readFileSync('src/secret-scanning/lib/config.json')) + // This test ensures that the configured page exists. If the page moves + // this test will fail. + test(`check if ${targetFilename} was moved`, async () => { + const page = await get(`/${targetFilename}`, { followRedirects: true }) + expect(page.statusCode).toBe(200) + }) +})