From 4c2448251a5edce7c150c6468597100ae36c7b7c Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Wed, 20 Dec 2023 19:13:57 +0100 Subject: [PATCH] Update Approve Rule action to also do updates --- .github/scripts/approve-rule.mjs | 100 ++++++++++++++++++++--------- .github/workflows/approve-rule.yml | 25 +++++++- 2 files changed, 94 insertions(+), 31 deletions(-) diff --git a/.github/scripts/approve-rule.mjs b/.github/scripts/approve-rule.mjs index 3c74c4a2f7..e4b75ef5b1 100644 --- a/.github/scripts/approve-rule.mjs +++ b/.github/scripts/approve-rule.mjs @@ -9,6 +9,8 @@ import { createOrCheckoutBranch, commitAndPush } from './commons.mjs'; +import { getRulePages } from 'act-tools/dist/utils/get-page-data.js'; +import { extractTestCases } from "act-tools/dist//build-examples/extract-test-cases.js"; const w3cDataFormat = 'D MMMM YYYY'; const isoDateFormat = 'YYYY-MM-DD'; @@ -22,11 +24,25 @@ if (!argv['skip-clone']) { } await createOrCheckoutBranch(config, argv.branch); +await archiveRule(config, argv.ruleId); await generateApprovedRulePages(config, argv.ruleId); -await updateRuleVersionsYaml(config, argv.ruleId); +await updateRuleVersionsYaml(config, argv.ruleId, argv.changes); await approveTestCaseJson(config, argv.ruleId); await commitAndPush(config, `Set ${argv.ruleId} to approved`); +async function archiveRule({ tmpDir }, ruleId) { + const ruleDir = `${tmpDir}content/rules/${ruleId}`; + if (!fs.existsSync(`${ruleDir}/index.md`)) { + return; + } + const ruleText = fs.readFileSync(`${ruleDir}/index.md`, 'utf8'); + const lastModified = ruleText.match(/last_modified:\s+(.*)/)?.[1] + assert(lastModified, `Unable to find last_modified data in ${ruleId}/index.md`); + + const date = moment(lastModified, w3cDataFormat).format(isoDateFormat) + await $`mv ${ruleDir}/index.md ${ruleDir}/${date}.md` +} + async function generateApprovedRulePages({ tmpDir, rulesDir, glossaryDir, testAssetsDir }, ruleId) { await $`node ./node_modules/act-tools/dist/cli/rule-transform.js \ --rulesDir "${rulesDir}" \ @@ -37,47 +53,71 @@ async function generateApprovedRulePages({ tmpDir, rulesDir, glossaryDir, testAs `; } -async function updateRuleVersionsYaml({ tmpDir }, ruleId) { +async function updateRuleVersionsYaml({ tmpDir }, ruleId, changes) { + if (typeof changes === 'string' && changes.length > 0) { + changes = [changes] + } else if (Array.isArray(changes)) { + changes = changes.filter(change => change.length > 0) + } else { + changes = [] + } + const ruleVersionPath = `${tmpDir}_data/wcag-act-rules/rule-versions.yml`; let ruleVersionsStr = fs.readFileSync(ruleVersionPath, 'utf8'); const ruleVersions = YAML.parse(ruleVersionsStr); - assert( - ruleVersions[ruleId] === undefined, - `RuleID ${ruleId} should not exists in rule-versions.yml. Was this rule approved before?` - ); - const proposedText = fs.readFileSync(`${tmpDir}content/rules/${ruleId}/proposed.md`, 'utf8'); - const proposedData = proposedText.match(/last_modified:\s+(.*)/)?.[1] - assert(proposedData, `Unable to find last_modified data in ${ruleId}/proposed.md`); + if (ruleVersions[ruleId] === undefined) { + const proposedText = fs.readFileSync(`${tmpDir}content/rules/${ruleId}/proposed.md`, 'utf8'); + const proposedData = proposedText.match(/last_modified:\s+(.*)/)?.[1] + assert(proposedData, `Unable to find last_modified data in ${ruleId}/proposed.md`); - ruleVersions[ruleId] = [{ - file: 'proposed.md', - url: `${ruleId}/proposed/`, - w3cDate: proposedData, - isoDate: moment(proposedData, w3cDataFormat).format(isoDateFormat) - }, { - file: 'index.md', - url: `${ruleId}/`, - w3cDate: moment().format(w3cDataFormat), - isoDate: moment().format(isoDateFormat) - }] + ruleVersions[ruleId] = [{ + file: 'proposed.md', + url: `${ruleId}/proposed/`, + w3cDate: proposedData, + isoDate: moment(proposedData, w3cDataFormat).format(isoDateFormat) + }, { + file: 'index.md', + url: `${ruleId}/`, + w3cDate: moment().format(w3cDataFormat), + isoDate: moment().format(isoDateFormat) + }] + } else { + ruleVersions[ruleId].forEach(entry => { + if (entry.file === 'index.md') { + entry.file = entry.isoDate + '.md'; + entry.url = `${ruleId}/${entry.isoDate}/`; + } + }) + // Insert the new index after 'proposed.md' + ruleVersions[ruleId].splice(1, 0, { + file: 'index.md', + url: `${ruleId}/`, + w3cDate: moment().format(w3cDataFormat), + isoDate: moment().format(isoDateFormat), + changes + }); + } ruleVersionsStr = YAML.stringify(ruleVersions); fs.writeFileSync(ruleVersionPath, ruleVersionsStr, 'utf8'); console.log(`Added ${ruleId} to rule-versions.yml`); } -async function approveTestCaseJson({ tmpDir }, ruleId) { - let testCaseCount = 0; +async function approveTestCaseJson({ tmpDir, rulesDir, testAssetsDir }, ruleId) { + const rulePages = getRulePages(rulesDir, testAssetsDir, [ruleId]); + const ruleTestCases = extractTestCases(rulePages[0]).map(({ metadata }) => { + metadata.approved = true; + return metadata; + }) + const testCaseJsonPath = `${tmpDir}content-assets/wcag-act-rules/testcases.json`; const testCaseJson = JSON.parse(fs.readFileSync(testCaseJsonPath, 'utf8')); - testCaseJson.testcases.forEach((testCase, index) => { - if (testCase.ruleId === ruleId) { - // Override rather than update so that `approved` isn't at the bottom - testCaseJson.testcases[index] = { ruleId, approved: true, ...testCase } - testCaseCount++ - } - }); - console.log(`Set ${testCaseCount} test cases of rule ${ruleId} to be approved in testcases.json`); + const testCases = testCaseJson.testcases.filter(testCase => testCase.ruleId !== ruleId); + testCaseJson.testcases = [ + ...ruleTestCases, + ...testCases + ] + console.log(`Set ${testCases.length} test cases of rule ${ruleId} to be approved in testcases.json`); fs.writeFileSync(testCaseJsonPath, JSON.stringify(testCaseJson, null, 2), 'utf8'); } diff --git a/.github/workflows/approve-rule.yml b/.github/workflows/approve-rule.yml index 28fd9504a7..bd7337e045 100644 --- a/.github/workflows/approve-rule.yml +++ b/.github/workflows/approve-rule.yml @@ -9,6 +9,21 @@ on: branch: description: 'Target branch name (new or existing)' required: true + change1: + description: 'Change 1 (only for updating approved rules)' + required: false + change2: + description: 'Change 2 (leave blank if not needed)' + required: false + change3: + description: 'Change 3' + required: false + change4: + description: 'Change 3' + required: false + change5: + description: 'Change 3' + required: false jobs: dispatch: @@ -38,4 +53,12 @@ jobs: git config --global user.name "${{ secrets.WAI_GIT_NAME }}" git config --global user.email "${{ secrets.WAI_GIT_EMAIL }}" - name: Set rule to approved - run: npx zx .github/scripts/approve-rule.mjs --ruleId "${{ github.event.inputs.ruleId }}" --branch "${{ github.event.inputs.branch }}" + run: | + npx zx .github/scripts/approve-rule.mjs \ + --ruleId "${{ github.event.inputs.ruleId }}" \ + --branch "${{ github.event.inputs.branch }}" \ + --changes "${{ github.event.inputs.change1 }}" \ + --changes "${{ github.event.inputs.change2 }}" \ + --changes "${{ github.event.inputs.change3 }}" \ + --changes "${{ github.event.inputs.change4 }}" \ + --changes "${{ github.event.inputs.change5 }}"