From c842450c8da6aaa13b450b12de368d68c79180d9 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 15 Aug 2025 14:08:33 +1000 Subject: [PATCH 01/25] Collate scan results in add-on metadata --- .../workflows/checkAndSubmitAddonMetadata.yml | 64 ++++--------------- .github/workflows/codeql-analysis.yml | 29 ++++++--- .github/workflows/securityAnalysis.js | 26 +++----- .github/workflows/virusScanAllAddons.yml | 28 ++------ .github/workflows/virusTotalAnalysis.js | 38 +++++------ reviewedAddons.json | 5 -- 6 files changed, 63 insertions(+), 127 deletions(-) delete mode 100644 reviewedAddons.json diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index 939f2fba67e..aca0277adb8 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -252,22 +252,13 @@ jobs: script: | const setVirusTotalAnalysisStatus = require('./.github/workflows/virusTotalAnalysis.js') setVirusTotalAnalysisStatus({core}, ["${{ needs.getAddonId.outputs.addonFileName }}"]) - - name: Upload results - id: uploadResults - if: failure() - uses: actions/upload-artifact@v4 - with: - name: VirusTotal - path: vt.json - overwrite: true - - name: Upload manual approval - id: uploadManualApproval - if: failure() - uses: actions/upload-artifact@v4 - with: - name: manualApproval - path: reviewedAddons.json - overwrite: true + - name: Commit scanned add-ons results + run: | + git add addons + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git commit -m "Add VirusTotal results" + git push --set-upstream origin ${{ env.branchName }} - name: Warn if analysis fails if: failure() uses: peter-evans/create-or-update-comment@v4 @@ -286,44 +277,13 @@ jobs: addonFileName: ${{ needs.getAddonId.outputs.addonFileName }} branchName: ${{ inputs.issueAuthorName }}${{ inputs.issueNumber }} - createManualApproval: + requireManualApproval: needs: [getAddonId, virusTotal-analysis, codeQL-analysis] if: ${{ always() && (contains(needs.virusTotal-analysis.result, 'failure') || contains(needs.codeQL-analysis.result, 'failure')) }} - runs-on: windows-latest - strategy: - matrix: - python-version: [ 3.11 ] - permissions: - contents: write - issues: write - pull-requests: write - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Download artifacts - uses: actions/download-artifact@v4 - with: - merge-multiple: true - - name: Create pull request - id: cpr - uses: peter-evans/create-pull-request@v7 - with: - add-paths: reviewedAddons.json - title: Add reviewed add-on (${{ needs.getAddonId.outputs.addonId }}) - branch: reviewedAddon${{ github.event.issue.number }} - commit-message: Add reviewed add-on (${{ needs.getAddonId.outputs.addonId }}) - body: | - This add-on needs to be reviewed by NV Access due to analysis failure. - Review #${{ inputs.issueNumber }} for more information. - author: github-actions - delete-branch: true - - name: Request to keep issue opened - uses: peter-evans/create-or-update-comment@v4 - with: - issue-number: ${{ inputs.issueNumber }} - body: | - Please, don't close this issue. - Wait until #${{ steps.cpr.outputs.pull-request-number }} is merged. + runs-on: ubuntu-latest + environment: + # Require a manual deployment approval if security analysis fails + name: securityReview mergeToMaster: needs: [getAddonId, createPullRequest, codeQL-analysis, virusTotal-analysis] diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 92302ef67fe..6ed8a51bda5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -51,7 +51,15 @@ jobs: script: | const setSecurityAnalysisStatus = require('./.github/workflows/securityAnalysis.js') const resultsPath = 'results/python.sarif' - setSecurityAnalysisStatus({core}, "${{ inputs.addonFileName }}", resultsPath) + setSecurityAnalysisStatus({core}, "${{ inputs.addonFileName }}", resultsPath, "errors") + - name: Commit scanned add-ons results + if: always() + run: | + git add ${{ inputs.addonFileName }} + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git commit -m "Add CodeQL error results" + git push --set-upstream origin ${{ inputs.branchName }} - name: Upload results id: uploadResults if: failure() @@ -59,14 +67,6 @@ jobs: with: name: results-excluding-warnings path: results/python.sarif - - name: Upload manual approval - id: uploadManualApproval - if: failure() - uses: actions/upload-artifact@v4 - with: - name: manualApproval - path: reviewedAddons.json - overwrite: true - name: Warn if analysis fails if: failure() uses: peter-evans/create-or-update-comment@v4 @@ -122,7 +122,16 @@ jobs: script: | const setSecurityAnalysisStatus = require('./.github/workflows/securityAnalysis.js') const resultsPath = 'results/python.sarif' - setSecurityAnalysisStatus({core}, "${{ inputs.addonFileName }}", resultsPath) + setSecurityAnalysisStatus({core}, "${{ inputs.addonFileName }}", resultsPath, "warnings") + - name: Commit scanned add-ons results + if: always() + run: | + git pull + git add ${{ inputs.addonFileName }} + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git commit -m "Add CodeQL warnings results" + git push --set-upstream origin ${{ inputs.branchName }} - name: Upload results id: uploadResults if: failure() diff --git a/.github/workflows/securityAnalysis.js b/.github/workflows/securityAnalysis.js index 7149e3b6b4c..5c4b5a04f4d 100644 --- a/.github/workflows/securityAnalysis.js +++ b/.github/workflows/securityAnalysis.js @@ -1,28 +1,20 @@ -module.exports = ({core}, addonMetadataPath, resultsPath) => { +module.exports = ({core}, addonMetadataPath, resultsPath, testType) => { const fs = require('fs'); const addonMetadataContents = fs.readFileSync(addonMetadataPath); const addonMetadata = JSON.parse(addonMetadataContents); - const addonId = addonMetadata.addonId; - const sha256 = addonMetadata.sha256; - const reviewedAddonsContents = fs.readFileSync('reviewedAddons.json'); - const reviewedAddonsData = JSON.parse(reviewedAddonsContents); - if (reviewedAddonsData[addonId] !== undefined && reviewedAddonsData[addonId].includes(sha256)) { - core.info('Analysis skipped'); - return; - } const contents = fs.readFileSync(resultsPath); const data = JSON.parse(contents); const runs = data.runs[0]; const results = runs.results; + if (addonMetadata.scanResults === undefined) { + addonMetadata.scanResults = {}; + } + addonMetadata.scanResults[`codeQL-${testType}`] = results; + const stringified = JSON.stringify(addonMetadata, null, "\t"); + fs.writeFileSync(addonMetadataPath, stringified + "\n"); if (results.length === 0) { core.info("Security analysis succeeded"); - return; - } - if (reviewedAddonsData[addonId] === undefined) { - reviewedAddonsData[addonId] = []; + } else { + core.setFailed("Security analysis failed"); } - reviewedAddonsData[addonId].push(sha256); - const stringified = JSON.stringify(reviewedAddonsData, null, "\t"); - fs.writeFileSync('reviewedAddons.json', stringified); - core.setFailed("Security analysis failed"); }; diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index c4702aa2f13..da6ed9f06e8 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -24,7 +24,7 @@ jobs: VT_API_KEY: ${{ secrets.VT_API_KEY }} VT_API_LIMIT: ${{ vars.VT_API_LIMIT }} BRANCH_NAME: addVTURLs${{ github.run_number }} - BATCH_SIZE: 100 + BATCH_SIZE: 10 steps: - name: Checkout repository uses: actions/checkout@v4 @@ -39,11 +39,11 @@ jobs: uses: actions/setup-node@v4 - name: Install npm dependencies run: npm install glob uuid - - name: Get add-on filenames without vtScanUrl + - name: Get add-on filenames without scanResults shell: bash run: | for file in ./addons/*/*.json; do - if (jq -r '.vtScanUrl' "$file" | grep -q 'null\|""'); then + if (jq -r '.scanResults' "$file" | grep -q 'null\|""'); then echo "$file" >> addonsWithoutVT.txt fi done @@ -63,29 +63,13 @@ jobs: git add addons git config user.name "github-actions" git config user.email "github-actions@github.com" - git commit -m "Add VirusTotal review URLs" + git commit -m "Add VirusTotal results" git push --set-upstream origin ${{ env.BRANCH_NAME }} gh pr create \ - --title "Add VirusTotal review URLs" \ + --title "Add VirusTotal results" \ --base ${{ github.ref }} \ --head ${{ env.BRANCH_NAME }} \ - --body "Add VirusTotal review URLs to add-ons" + --body "Add VirusTotal results to add-ons" gh pr merge --merge "${{ env.BRANCH_NAME }}" env: GH_TOKEN: ${{ github.token }} - - name: Upload results - id: uploadResults - if: failure() - uses: actions/upload-artifact@v4 - with: - name: VirusTotal - path: vt.json - overwrite: true - - name: Upload manual approval - id: uploadManualApproval - if: failure() - uses: actions/upload-artifact@v4 - with: - name: manualApproval - path: reviewedAddons.json - overwrite: true diff --git a/.github/workflows/virusTotalAnalysis.js b/.github/workflows/virusTotalAnalysis.js index c402fecd607..6b189009dd9 100644 --- a/.github/workflows/virusTotalAnalysis.js +++ b/.github/workflows/virusTotalAnalysis.js @@ -10,17 +10,16 @@ function writeVTScanUrl({core}, metadataFile, addonMetadata) { addonMetadata.vtScanUrl = vtScanUrl; stringified = JSON.stringify(addonMetadata, null, "\t"); // Write vtScanUrl to add-on metadata file - fs.writeFileSync(metadataFile, stringified); + fs.writeFileSync(metadataFile, stringified + "\n"); // Store the latest vtScanUrl for single file analysis core.setOutput("vtScanUrl", vtScanUrl); } -function getVirusTotalAnalysis({core}, addonMetadata, metadataFile, reviewedAddonsData) { +function getVirusTotalAnalysis({core}, addonMetadata, metadataFile) { /* Get the VirusTotal analysis for the add-on file. - If the add-on is flagged as malicious, store the sha256 hash in reviewedAddons.json. - Always store the scan URL in the add-on metadata file. + store the results in the metadata file and the scan URL in the add-on metadata file. If Virus total fails to scan the add-on, fail the job. */ countAPIUsageAndWait({core}); @@ -33,26 +32,26 @@ function getVirusTotalAnalysis({core}, addonMetadata, metadataFile, reviewedAddo if (core._isSingleFileAnalysis) { core.setFailed(`Failed to get VirusTotal analysis for ${metadataFile}`); } + // Resubmit and try again virusTotalSubmit({core}, [metadataFile]); - getVirusTotalAnalysis({core}, addonMetadata, metadataFile, reviewedAddonsData); + getVirusTotalAnalysis({core}, addonMetadata, metadataFile); return; } writeVTScanUrl({core}, metadataFile, addonMetadata); // Append the VirusTotal analysis to the file for an artifact const vtData = JSON.parse(stdout); - fs.appendFileSync("vt.json", stdout); const stats = vtData[0]["last_analysis_stats"]; const malicious = stats.malicious; if (malicious === 0) { core.info(`VirusTotal analysis succeeded for ${metadataFile}`); return; } - if (reviewedAddonsData[addonMetadata.addonId] === undefined) { - reviewedAddonsData[addonMetadata.addonId] = []; + if (addonMetadata.scanResults === undefined) { + addonMetadata.scanResults = {}; } - reviewedAddonsData[addonMetadata.addonId].push(addonMetadata.sha256); - stringified = JSON.stringify(reviewedAddonsData, null, "\t"); - fs.writeFileSync("reviewedAddons.json", stringified); + addonMetadata.scanResults.virusTotal = vtData; + stringified = JSON.stringify(addonMetadata, null, "\t"); + fs.writeFileSync(metadataFile, stringified + "\n"); if (core._isSingleFileAnalysis) { core.setFailed(`VirusTotal analysis failed for ${metadataFile}`); } @@ -68,20 +67,17 @@ function getVirusTotalAnalysisIfRequired({core}, metadataFile) { */ const addonMetadataContents = fs.readFileSync(metadataFile); const addonMetadata = JSON.parse(addonMetadataContents); - const addonId = addonMetadata.addonId; - const reviewedAddonsContents = fs.readFileSync("reviewedAddons.json"); - const reviewedAddonsData = JSON.parse(reviewedAddonsContents); - // Check if add-on has been flagged before through VirusTotal. - if (reviewedAddonsData[addonId] !== undefined && reviewedAddonsData[addonId].includes(sha256)) { - core.info(`VirusTotal analysis skipped, already performed for ${metadataFile}`); - return; + // Check if add-on has been submitted before to VirusTotal. + if (addonMetadata.vtScanUrl === undefined) { + core.info(`VirusTotal scanning has not been performed for ${metadataFile}`); + virusTotalSubmit({core}, [metadataFile]); } - // Check if add-on has been scanned before through VirusTotal. - if (addonMetadata.vtScanUrl !== undefined) { + // Check if add-on has had results saved before through VirusTotal. + if (addonMetadata.scanResults !== undefined && addonMetadata.scanResults.virusTotal !== undefined) { core.info(`VirusTotal analysis skipped, already performed for ${metadataFile}`); return; } - getVirusTotalAnalysis({core}, addonMetadata, metadataFile, reviewedAddonsData); + getVirusTotalAnalysis({core}, addonMetadata, metadataFile); } module.exports = ({core}, metadataFiles) => { diff --git a/reviewedAddons.json b/reviewedAddons.json deleted file mode 100644 index 5c83299f7f6..00000000000 --- a/reviewedAddons.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "deltaTalk": [ - "f1aae0c1a1fb8a3fbbf72d3050629ffb9b1cf8e9daf105089a317d744f1e0790" - ] -} \ No newline at end of file From 635e69705bf3499ac5b77063b014450fef183550 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 15 Aug 2025 14:20:53 +1000 Subject: [PATCH 02/25] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Sean Budd --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/virusTotalAnalysis.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6ed8a51bda5..aec556944d6 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -126,7 +126,7 @@ jobs: - name: Commit scanned add-ons results if: always() run: | - git pull + git pull --rebase git add ${{ inputs.addonFileName }} git config user.name "github-actions" git config user.email "github-actions@github.com" diff --git a/.github/workflows/virusTotalAnalysis.js b/.github/workflows/virusTotalAnalysis.js index 6b189009dd9..a9b13a1c80c 100644 --- a/.github/workflows/virusTotalAnalysis.js +++ b/.github/workflows/virusTotalAnalysis.js @@ -19,7 +19,7 @@ function writeVTScanUrl({core}, metadataFile, addonMetadata) { function getVirusTotalAnalysis({core}, addonMetadata, metadataFile) { /* Get the VirusTotal analysis for the add-on file. - store the results in the metadata file and the scan URL in the add-on metadata file. + Store the results in the metadata file and the scan URL in the add-on metadata file. If Virus total fails to scan the add-on, fail the job. */ countAPIUsageAndWait({core}); From 9714a3ba72ebaf46ed79d43039094dd04b9f9329 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 15 Aug 2025 14:22:27 +1000 Subject: [PATCH 03/25] check testType --- .github/workflows/securityAnalysis.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/securityAnalysis.js b/.github/workflows/securityAnalysis.js index 5c4b5a04f4d..75583ad4840 100644 --- a/.github/workflows/securityAnalysis.js +++ b/.github/workflows/securityAnalysis.js @@ -6,6 +6,9 @@ module.exports = ({core}, addonMetadataPath, resultsPath, testType) => { const data = JSON.parse(contents); const runs = data.runs[0]; const results = runs.results; + if (testType !== "errors" && testType !== "warnings") { + core.setFailed(`Invalid test type: ${testType}`); + } if (addonMetadata.scanResults === undefined) { addonMetadata.scanResults = {}; } From b5933b12ca59edcb25edba3be717c55d0d030ffd Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 15 Aug 2025 14:30:30 +1000 Subject: [PATCH 04/25] fix up approval --- .github/workflows/checkAndSubmitAddonMetadata.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index aca0277adb8..c2c43a640ee 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -279,14 +279,15 @@ jobs: requireManualApproval: needs: [getAddonId, virusTotal-analysis, codeQL-analysis] - if: ${{ always() && (contains(needs.virusTotal-analysis.result, 'failure') || contains(needs.codeQL-analysis.result, 'failure')) }} + if: ${{ always() && (needs.virusTotal-analysis.result == 'failure' || needs.codeQL-analysis.result == 'failure') }} runs-on: ubuntu-latest environment: # Require a manual deployment approval if security analysis fails name: securityReview mergeToMaster: - needs: [getAddonId, createPullRequest, codeQL-analysis, virusTotal-analysis] + needs: [getAddonId, createPullRequest, requireManualApproval] + if: ${{ always() && (needs.requireManualApproval.result == 'success' || needs.requireManualApproval.result == 'skipped') }} permissions: contents: write pull-requests: write From 02d2d2d19eed7f380b11f33bf7eb8f17a1b034ca Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 15 Aug 2025 14:32:04 +1000 Subject: [PATCH 05/25] fix up approval --- .github/workflows/checkAndSubmitAddonMetadata.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index c2c43a640ee..01796347b89 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -284,6 +284,9 @@ jobs: environment: # Require a manual deployment approval if security analysis fails name: securityReview + steps: + - name: Confirm approval + run: echo "Manual approval performed" mergeToMaster: needs: [getAddonId, createPullRequest, requireManualApproval] From 824485172afe62c93d472239a387387d18cac77a Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 15 Aug 2025 14:47:17 +1000 Subject: [PATCH 06/25] fix up filtering --- .github/workflows/virusScanAllAddons.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index da6ed9f06e8..92d40aceccf 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -39,15 +39,15 @@ jobs: uses: actions/setup-node@v4 - name: Install npm dependencies run: npm install glob uuid - - name: Get add-on filenames without scanResults + - name: Get add-on filenames without scan results shell: bash run: | for file in ./addons/*/*.json; do - if (jq -r '.scanResults' "$file" | grep -q 'null\|""'); then + if (jq -r '.scanResults | .virusTotal' "$file" | grep -q 'null\|""'); then echo "$file" >> addonsWithoutVT.txt fi done - wc -l addonsWithoutVT.txt | awk '{print "Total add-ons without VT URLs: " $1}' + wc -l addonsWithoutVT.txt | awk '{print "Total add-ons without scan results: " $1}' - name: Set Virus Total analysis status id: setVirusTotalAnalysisStatus uses: actions/github-script@v7 From 8af58f864d5b0ffa9cb4027e6ac44e211664e9da Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 15 Aug 2025 14:50:20 +1000 Subject: [PATCH 07/25] fix writing --- .github/workflows/virusScanAllAddons.yml | 2 +- .github/workflows/virusTotalAnalysis.js | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index 92d40aceccf..bfeed43c2bd 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -23,7 +23,7 @@ jobs: env: VT_API_KEY: ${{ secrets.VT_API_KEY }} VT_API_LIMIT: ${{ vars.VT_API_LIMIT }} - BRANCH_NAME: addVTURLs${{ github.run_number }} + BRANCH_NAME: addVTresults${{ github.run_number }} BATCH_SIZE: 10 steps: - name: Checkout repository diff --git a/.github/workflows/virusTotalAnalysis.js b/.github/workflows/virusTotalAnalysis.js index a9b13a1c80c..8be8717505e 100644 --- a/.github/workflows/virusTotalAnalysis.js +++ b/.github/workflows/virusTotalAnalysis.js @@ -42,17 +42,16 @@ function getVirusTotalAnalysis({core}, addonMetadata, metadataFile) { const vtData = JSON.parse(stdout); const stats = vtData[0]["last_analysis_stats"]; const malicious = stats.malicious; - if (malicious === 0) { - core.info(`VirusTotal analysis succeeded for ${metadataFile}`); - return; - } if (addonMetadata.scanResults === undefined) { addonMetadata.scanResults = {}; } addonMetadata.scanResults.virusTotal = vtData; stringified = JSON.stringify(addonMetadata, null, "\t"); fs.writeFileSync(metadataFile, stringified + "\n"); - if (core._isSingleFileAnalysis) { + if (malicious === 0) { + core.info(`VirusTotal analysis succeeded for ${metadataFile}`); + } + else if (core._isSingleFileAnalysis) { core.setFailed(`VirusTotal analysis failed for ${metadataFile}`); } }); From 7ace949f4184bb40209dff579ac80457e379370e Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 15 Aug 2025 15:32:13 +1000 Subject: [PATCH 08/25] update python version and fix permissions --- .github/workflows/checkAndSubmitAddonMetadata.yml | 14 +++++++------- .github/workflows/regenerateTranslations.yml | 2 +- .github/workflows/transformDataToViews.yml | 2 +- .github/workflows/validateAllAddons.yml | 2 +- .github/workflows/virusScanAllAddons.yml | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index 01796347b89..20ee3951fc2 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -27,7 +27,7 @@ jobs: runs-on: windows-latest strategy: matrix: - python-version: [ 3.11 ] + python-version: [ 3.13 ] permissions: contents: write issues: write @@ -83,7 +83,7 @@ jobs: needs: [getAddonId] strategy: matrix: - python-version: [ 3.11 ] + python-version: [ 3.13 ] permissions: contents: write pull-requests: write @@ -151,7 +151,7 @@ jobs: needs: [getAddonId, verifySubmitter] strategy: matrix: - python-version: [ 3.11 ] + python-version: [ 3.13 ] permissions: contents: write pull-requests: write @@ -225,9 +225,9 @@ jobs: runs-on: windows-latest strategy: matrix: - python-version: [ 3.11 ] + python-version: [ 3.13 ] permissions: - contents: read + contents: write issues: write env: VT_API_KEY: ${{ secrets.VT_API_KEY }} @@ -297,7 +297,7 @@ jobs: runs-on: windows-latest strategy: matrix: - python-version: [ 3.11 ] + python-version: [ 3.13 ] steps: - name: Checkout code uses: actions/checkout@v4 @@ -314,7 +314,7 @@ jobs: needs: [getAddonId, mergeToMaster, virusTotal-analysis] strategy: matrix: - python-version: [ 3.11 ] + python-version: [ 3.13 ] permissions: contents: write discussions: write diff --git a/.github/workflows/regenerateTranslations.yml b/.github/workflows/regenerateTranslations.yml index b65705509ff..f44f8c1e0cc 100644 --- a/.github/workflows/regenerateTranslations.yml +++ b/.github/workflows/regenerateTranslations.yml @@ -10,7 +10,7 @@ jobs: runs-on: windows-latest strategy: matrix: - python-version: [ 3.11 ] + python-version: [ 3.13 ] steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/.github/workflows/transformDataToViews.yml b/.github/workflows/transformDataToViews.yml index fa7d5bd2661..9f2959b9514 100644 --- a/.github/workflows/transformDataToViews.yml +++ b/.github/workflows/transformDataToViews.yml @@ -20,7 +20,7 @@ jobs: COMMIT_FORMAT: "Generated from %h%n%nCommit message:%n%s%n%b" strategy: matrix: - python-version: [ 3.11 ] + python-version: [ 3.13 ] steps: - name: Checkout addon data uses: actions/checkout@v4 diff --git a/.github/workflows/validateAllAddons.yml b/.github/workflows/validateAllAddons.yml index 2a6eb660f41..34fe6c049bb 100644 --- a/.github/workflows/validateAllAddons.yml +++ b/.github/workflows/validateAllAddons.yml @@ -14,7 +14,7 @@ jobs: runs-on: windows-latest strategy: matrix: - python-version: [ 3.11 ] + python-version: [ 3.13 ] steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index bfeed43c2bd..225fb03565e 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -16,7 +16,7 @@ jobs: runs-on: windows-latest strategy: matrix: - python-version: [ 3.11 ] + python-version: [ 3.13 ] permissions: contents: write pull-requests: write From 861f6bbebb5594ef1942b93e400756e8cae890c7 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 15 Aug 2025 15:34:22 +1000 Subject: [PATCH 09/25] fix perms --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index aec556944d6..bc25cbe2233 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -16,7 +16,7 @@ jobs: runs-on: windows-latest permissions: actions: read - contents: read + contents: write security-events: write issues: write steps: From b59e8f84574a179019de907441e4f715b8be1809 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 15 Aug 2025 15:47:30 +1000 Subject: [PATCH 10/25] pull before pushing --- .github/workflows/checkAndSubmitAddonMetadata.yml | 3 ++- .github/workflows/codeql-analysis.yml | 3 ++- .github/workflows/sendJsonFile.yml | 9 +++++---- .github/workflows/transformDataToViews.yml | 1 + .github/workflows/virusScanAllAddons.yml | 1 + 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index 20ee3951fc2..29696a7f417 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -258,6 +258,7 @@ jobs: git config user.name "github-actions" git config user.email "github-actions@github.com" git commit -m "Add VirusTotal results" + git pull --rebase git push --set-upstream origin ${{ env.branchName }} - name: Warn if analysis fails if: failure() @@ -409,7 +410,7 @@ jobs: git add . git commit -m "update discussion URL" git branch -u origin/master - git pull + git pull --rebase git push call-workflow: diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index bc25cbe2233..1850a1c8534 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -59,6 +59,7 @@ jobs: git config user.name "github-actions" git config user.email "github-actions@github.com" git commit -m "Add CodeQL error results" + git pull --rebase git push --set-upstream origin ${{ inputs.branchName }} - name: Upload results id: uploadResults @@ -126,11 +127,11 @@ jobs: - name: Commit scanned add-ons results if: always() run: | - git pull --rebase git add ${{ inputs.addonFileName }} git config user.name "github-actions" git config user.email "github-actions@github.com" git commit -m "Add CodeQL warnings results" + git pull --rebase git push --set-upstream origin ${{ inputs.branchName }} - name: Upload results id: uploadResults diff --git a/.github/workflows/sendJsonFile.yml b/.github/workflows/sendJsonFile.yml index 659eeef087e..e958b1b077a 100644 --- a/.github/workflows/sendJsonFile.yml +++ b/.github/workflows/sendJsonFile.yml @@ -77,16 +77,17 @@ jobs: body-file: ./validationErrors.md - name: Create branch id: cb + env: + branchName: ${{ github.event.issue.user.login }}${{ steps.get-data.outputs.issueNumber }} run: | cd datastore git config user.name github-actions git config user.email github-actions@github.com - git checkout -b ${{ github.event.issue.user.login }}${{ steps.get-data.outputs.issueNumber }} - git pull + git checkout -b ${{ env.branchName }} git add . git commit -m "Submit add-on" - # Force push to the branch, as we may need to be handling a resubmission attempt - git push -f origin ${{ github.event.issue.user.login }}${{ steps.get-data.outputs.issueNumber }} + git pull --rebase + git push --set-upstream origin ${{ env.branchName }} - name: Upload add-on uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/transformDataToViews.yml b/.github/workflows/transformDataToViews.yml index 9f2959b9514..9a40abfd86c 100644 --- a/.github/workflows/transformDataToViews.yml +++ b/.github/workflows/transformDataToViews.yml @@ -65,4 +65,5 @@ jobs: git config user.email github-actions@github.com git add . git commit -F ../commitMsg.txt + git pull --rebase git push diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index 225fb03565e..4834d7762f3 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -64,6 +64,7 @@ jobs: git config user.name "github-actions" git config user.email "github-actions@github.com" git commit -m "Add VirusTotal results" + git pull --rebase git push --set-upstream origin ${{ env.BRANCH_NAME }} gh pr create \ --title "Add VirusTotal results" \ From f04fe7b61f1501b9dab59c0aa795604270543d5b Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 21 Aug 2025 11:38:08 +1000 Subject: [PATCH 11/25] handle results collation better --- .../workflows/checkAndSubmitAddonMetadata.yml | 33 ++++++++++++++++++- .github/workflows/codeql-analysis.yml | 33 ++++++++----------- .github/workflows/securityAnalysis.js | 9 ++--- .github/workflows/virusTotalAnalysis.js | 17 +++++++--- 4 files changed, 59 insertions(+), 33 deletions(-) diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index 29696a7f417..bc73ed8e9a6 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -234,6 +234,7 @@ jobs: VT_API_LIMIT: ${{ vars.VT_API_LIMIT }} outputs: vtScanUrl: ${{ steps.setVirusTotalAnalysisStatus.outputs.vtScanUrl }} + vtResultsJSON: ${{ steps.setVirusTotalAnalysisStatus.outputs.vtResults }} steps: - name: Checkout repository uses: actions/checkout@v4 @@ -278,8 +279,38 @@ jobs: addonFileName: ${{ needs.getAddonId.outputs.addonFileName }} branchName: ${{ inputs.issueAuthorName }}${{ inputs.issueNumber }} - requireManualApproval: + commitScanResults: needs: [getAddonId, virusTotal-analysis, codeQL-analysis] + if: ${{ always() }} + runs-on: ubuntu-latest + steps: + - name: Collate analysis results into add-on metadata + run: | + jq --argjson codeQLwarnings "${{ needs.codeQL-analysis.outputs.warningsJSON }}" \ + --argjson codeQLerrors "${{ needs.codeQL-analysis.outputs.errorsJSON }}" \ + --argjson vtResults "${{ needs.virusTotal-analysis.outputs.vtResultsJSON }}" \ + --arg vtScanUrl "${{ needs.virusTotal-analysis.outputs.vtScanUrl }}" \ + '. + { + vtScanUrl: $vtScanUrl, + scanResults: { + codeQL-warnings: $codeQLwarnings, + codeQL-errors: $codeQLerrors, + virusTotal: $vtResults + } + }' \ + addons/${{ needs.getAddonId.outputs.addonFileName }} > tmp.json + mv tmp.json addons/${{ needs.getAddonId.outputs.addonFileName }} + + - name: Commit add-ons metadata + run: | + git add ${{ needs.getAddonId.outputs.addonFileName }} + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git commit -m "Add code analysis results" + git push --set-upstream origin ${{ env.branchName }} + + requireManualApproval: + needs: [commitScanResults, virusTotal-analysis, codeQL-analysis] if: ${{ always() && (needs.virusTotal-analysis.result == 'failure' || needs.codeQL-analysis.result == 'failure') }} runs-on: ubuntu-latest environment: diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 1850a1c8534..89eafbcd520 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -9,6 +9,13 @@ on: branchName: required: true type: string + outputs: + warningsJSON: + description: "The JSON from CodeQL warnings" + value: ${{ jobs.analyzeExcludingWarnings.outputs.codeQLResults }} + errorsJSON: + description: "The JSON from CodeQL errors" + value: ${{ jobs.analyze.outputs.codeQLResults }} jobs: analyzeExcludingWarnings: @@ -19,6 +26,8 @@ jobs: contents: write security-events: write issues: write + outputs: + codeQLResults: ${{ steps.setSecurityAnalysisStatus.outputs.codeQLResults }} steps: - name: Checkout repository uses: actions/checkout@v4 @@ -51,16 +60,7 @@ jobs: script: | const setSecurityAnalysisStatus = require('./.github/workflows/securityAnalysis.js') const resultsPath = 'results/python.sarif' - setSecurityAnalysisStatus({core}, "${{ inputs.addonFileName }}", resultsPath, "errors") - - name: Commit scanned add-ons results - if: always() - run: | - git add ${{ inputs.addonFileName }} - git config user.name "github-actions" - git config user.email "github-actions@github.com" - git commit -m "Add CodeQL error results" - git pull --rebase - git push --set-upstream origin ${{ inputs.branchName }} + setSecurityAnalysisStatus({core}, "${{ inputs.addonFileName }}", resultsPath) - name: Upload results id: uploadResults if: failure() @@ -91,6 +91,8 @@ jobs: actions: read security-events: write issues: write + outputs: + codeQLResults: ${{ steps.setSecurityAnalysisStatus.outputs.codeQLResults }} steps: - name: Checkout repository uses: actions/checkout@v4 @@ -123,16 +125,7 @@ jobs: script: | const setSecurityAnalysisStatus = require('./.github/workflows/securityAnalysis.js') const resultsPath = 'results/python.sarif' - setSecurityAnalysisStatus({core}, "${{ inputs.addonFileName }}", resultsPath, "warnings") - - name: Commit scanned add-ons results - if: always() - run: | - git add ${{ inputs.addonFileName }} - git config user.name "github-actions" - git config user.email "github-actions@github.com" - git commit -m "Add CodeQL warnings results" - git pull --rebase - git push --set-upstream origin ${{ inputs.branchName }} + setSecurityAnalysisStatus({core}, "${{ inputs.addonFileName }}", resultsPath) - name: Upload results id: uploadResults if: failure() diff --git a/.github/workflows/securityAnalysis.js b/.github/workflows/securityAnalysis.js index 75583ad4840..5ea75371e99 100644 --- a/.github/workflows/securityAnalysis.js +++ b/.github/workflows/securityAnalysis.js @@ -1,4 +1,4 @@ -module.exports = ({core}, addonMetadataPath, resultsPath, testType) => { +module.exports = ({core}, addonMetadataPath, resultsPath) => { const fs = require('fs'); const addonMetadataContents = fs.readFileSync(addonMetadataPath); const addonMetadata = JSON.parse(addonMetadataContents); @@ -6,15 +6,10 @@ module.exports = ({core}, addonMetadataPath, resultsPath, testType) => { const data = JSON.parse(contents); const runs = data.runs[0]; const results = runs.results; - if (testType !== "errors" && testType !== "warnings") { - core.setFailed(`Invalid test type: ${testType}`); - } if (addonMetadata.scanResults === undefined) { addonMetadata.scanResults = {}; } - addonMetadata.scanResults[`codeQL-${testType}`] = results; - const stringified = JSON.stringify(addonMetadata, null, "\t"); - fs.writeFileSync(addonMetadataPath, stringified + "\n"); + core.setOutput("codeQLResults", results); if (results.length === 0) { core.info("Security analysis succeeded"); } else { diff --git a/.github/workflows/virusTotalAnalysis.js b/.github/workflows/virusTotalAnalysis.js index 8be8717505e..7279bbc0e89 100644 --- a/.github/workflows/virusTotalAnalysis.js +++ b/.github/workflows/virusTotalAnalysis.js @@ -9,10 +9,12 @@ function writeVTScanUrl({core}, metadataFile, addonMetadata) { const vtScanUrl = `https://www.virustotal.com/gui/file/${addonMetadata.sha256}`; addonMetadata.vtScanUrl = vtScanUrl; stringified = JSON.stringify(addonMetadata, null, "\t"); - // Write vtScanUrl to add-on metadata file - fs.writeFileSync(metadataFile, stringified + "\n"); - // Store the latest vtScanUrl for single file analysis - core.setOutput("vtScanUrl", vtScanUrl); + if (core._isSingleFileAnalysis) { + core.setOutput("vtScanUrl", vtScanUrl); + } + else { + fs.writeFileSync(metadataFile, stringified + "\n"); + } } @@ -47,7 +49,12 @@ function getVirusTotalAnalysis({core}, addonMetadata, metadataFile) { } addonMetadata.scanResults.virusTotal = vtData; stringified = JSON.stringify(addonMetadata, null, "\t"); - fs.writeFileSync(metadataFile, stringified + "\n"); + if (core._isSingleFileAnalysis) { + core.setOutput("vtResults", vtData); + } + else { + fs.writeFileSync(metadataFile, stringified + "\n"); + } if (malicious === 0) { core.info(`VirusTotal analysis succeeded for ${metadataFile}`); } From 1f31bf66e02ff409a6833eed9da9077f98e799ba Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 21 Aug 2025 12:18:41 +1000 Subject: [PATCH 12/25] clean up --- .../workflows/checkAndSubmitAddonMetadata.yml | 23 ++++++++----------- .github/workflows/codeql-analysis.yml | 6 ++--- .github/workflows/securityAnalysis.js | 7 +----- .github/workflows/transformDataToViews.yml | 1 - .github/workflows/virusScanAllAddons.yml | 2 +- .github/workflows/virusTotalAnalysis.js | 17 +++++++------- .github/workflows/virusTotalSubmit.js | 1 - 7 files changed, 22 insertions(+), 35 deletions(-) diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index 990c974f5b9..bb8b1c1cfbf 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -227,7 +227,7 @@ jobs: matrix: python-version: [ 3.13 ] permissions: - contents: write + contents: read issues: write env: VT_API_KEY: ${{ secrets.VT_API_KEY }} @@ -242,8 +242,8 @@ jobs: ref: ${{ env.branchName }} - name: Install Node.js uses: actions/setup-node@v4 - - name: Install glob - run: npm install glob uuid + - name: Install npm dependencies + run: npm install uuid - name: Install virusTotal run: choco install vt-cli - name: Set Virus Total analysis status @@ -253,14 +253,6 @@ jobs: script: | const setVirusTotalAnalysisStatus = require('./.github/workflows/virusTotalAnalysis.js') setVirusTotalAnalysisStatus({core}, ["${{ needs.getAddonId.outputs.addonFileName }}"]) - - name: Commit scanned add-ons results - run: | - git add addons - git config user.name "github-actions" - git config user.email "github-actions@github.com" - git commit -m "Add VirusTotal results" - git pull --rebase - git push --set-upstream origin ${{ env.branchName }} - name: Warn if analysis fails if: failure() uses: peter-evans/create-or-update-comment@v4 @@ -284,6 +276,10 @@ jobs: if: ${{ always() }} runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + ref: ${{ env.branchName }} - name: Collate analysis results into add-on metadata run: | jq --argjson codeQLwarnings "${{ needs.codeQL-analysis.outputs.warningsJSON }}" \ @@ -300,8 +296,7 @@ jobs: }' \ addons/${{ needs.getAddonId.outputs.addonFileName }} > tmp.json mv tmp.json addons/${{ needs.getAddonId.outputs.addonFileName }} - - - name: Commit add-ons metadata + - name: Commit add-on metadata run: | git add ${{ needs.getAddonId.outputs.addonFileName }} git config user.name "github-actions" @@ -441,7 +436,7 @@ jobs: git add . git commit -m "update discussion URL" git branch -u origin/master - git pull --rebase + git pull git push call-workflow: diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c0a42935505..b74b72ce48d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -23,7 +23,7 @@ jobs: runs-on: windows-latest permissions: actions: read - contents: write + contents: read security-events: write issues: write outputs: @@ -60,7 +60,7 @@ jobs: script: | const setSecurityAnalysisStatus = require('./.github/workflows/securityAnalysis.js') const resultsPath = 'results/python.sarif' - setSecurityAnalysisStatus({core}, "${{ inputs.addonFileName }}", resultsPath) + setSecurityAnalysisStatus({core}, resultsPath) - name: Upload results id: uploadResults if: failure() @@ -125,7 +125,7 @@ jobs: script: | const setSecurityAnalysisStatus = require('./.github/workflows/securityAnalysis.js') const resultsPath = 'results/python.sarif' - setSecurityAnalysisStatus({core}, "${{ inputs.addonFileName }}", resultsPath) + setSecurityAnalysisStatus({core}, resultsPath) - name: Upload results id: uploadResults if: failure() diff --git a/.github/workflows/securityAnalysis.js b/.github/workflows/securityAnalysis.js index 5ea75371e99..a94b7f13384 100644 --- a/.github/workflows/securityAnalysis.js +++ b/.github/workflows/securityAnalysis.js @@ -1,14 +1,9 @@ -module.exports = ({core}, addonMetadataPath, resultsPath) => { +module.exports = ({core}, resultsPath) => { const fs = require('fs'); - const addonMetadataContents = fs.readFileSync(addonMetadataPath); - const addonMetadata = JSON.parse(addonMetadataContents); const contents = fs.readFileSync(resultsPath); const data = JSON.parse(contents); const runs = data.runs[0]; const results = runs.results; - if (addonMetadata.scanResults === undefined) { - addonMetadata.scanResults = {}; - } core.setOutput("codeQLResults", results); if (results.length === 0) { core.info("Security analysis succeeded"); diff --git a/.github/workflows/transformDataToViews.yml b/.github/workflows/transformDataToViews.yml index 12875198987..97da31a7ee9 100644 --- a/.github/workflows/transformDataToViews.yml +++ b/.github/workflows/transformDataToViews.yml @@ -65,5 +65,4 @@ jobs: git config user.email github-actions@github.com git add . git commit -F ../commitMsg.txt - git pull --rebase git push diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index 598c2c36aed..4c1b5746e4f 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -38,7 +38,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@v4 - name: Install npm dependencies - run: npm install glob uuid + run: npm install uuid - name: Get add-on filenames without scan results shell: bash run: | diff --git a/.github/workflows/virusTotalAnalysis.js b/.github/workflows/virusTotalAnalysis.js index 7279bbc0e89..135890e8a45 100644 --- a/.github/workflows/virusTotalAnalysis.js +++ b/.github/workflows/virusTotalAnalysis.js @@ -1,4 +1,3 @@ -const glob = require("glob"); const fs = require("fs"); const { exec } = require("child_process"); const countAPIUsageAndWait = require("./virusTotalAPISleepAndCount"); @@ -7,12 +6,12 @@ const virusTotalSubmit = require("./virusTotalSubmit"); function writeVTScanUrl({core}, metadataFile, addonMetadata) { const vtScanUrl = `https://www.virustotal.com/gui/file/${addonMetadata.sha256}`; - addonMetadata.vtScanUrl = vtScanUrl; - stringified = JSON.stringify(addonMetadata, null, "\t"); if (core._isSingleFileAnalysis) { core.setOutput("vtScanUrl", vtScanUrl); } else { + addonMetadata.vtScanUrl = vtScanUrl; + stringified = JSON.stringify(addonMetadata, null, "\t"); fs.writeFileSync(metadataFile, stringified + "\n"); } } @@ -44,15 +43,15 @@ function getVirusTotalAnalysis({core}, addonMetadata, metadataFile) { const vtData = JSON.parse(stdout); const stats = vtData[0]["last_analysis_stats"]; const malicious = stats.malicious; - if (addonMetadata.scanResults === undefined) { - addonMetadata.scanResults = {}; - } - addonMetadata.scanResults.virusTotal = vtData; - stringified = JSON.stringify(addonMetadata, null, "\t"); if (core._isSingleFileAnalysis) { core.setOutput("vtResults", vtData); } else { + if (addonMetadata.scanResults === undefined) { + addonMetadata.scanResults = {}; + } + addonMetadata.scanResults.virusTotal = vtData; + stringified = JSON.stringify(addonMetadata, null, "\t"); fs.writeFileSync(metadataFile, stringified + "\n"); } if (malicious === 0) { @@ -80,7 +79,7 @@ function getVirusTotalAnalysisIfRequired({core}, metadataFile) { } // Check if add-on has had results saved before through VirusTotal. if (addonMetadata.scanResults !== undefined && addonMetadata.scanResults.virusTotal !== undefined) { - core.info(`VirusTotal analysis skipped, already performed for ${metadataFile}`); + core.info(`VirusTotal results fetch skipped, already performed for ${metadataFile}`); return; } getVirusTotalAnalysis({core}, addonMetadata, metadataFile); diff --git a/.github/workflows/virusTotalSubmit.js b/.github/workflows/virusTotalSubmit.js index b44e7ecf9f6..0f0b61ab888 100644 --- a/.github/workflows/virusTotalSubmit.js +++ b/.github/workflows/virusTotalSubmit.js @@ -1,4 +1,3 @@ -const glob = require("glob"); const { v4: uuidv4 } = require("uuid"); const fs = require("fs"); const { exec } = require("child_process"); From 3d9e336ea443c0fbd550c3592658e7aa1568e873 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 21 Aug 2025 12:32:35 +1000 Subject: [PATCH 13/25] fix quotations --- .github/workflows/checkAndSubmitAddonMetadata.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index bb8b1c1cfbf..ab0346f20c1 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -282,10 +282,10 @@ jobs: ref: ${{ env.branchName }} - name: Collate analysis results into add-on metadata run: | - jq --argjson codeQLwarnings "${{ needs.codeQL-analysis.outputs.warningsJSON }}" \ - --argjson codeQLerrors "${{ needs.codeQL-analysis.outputs.errorsJSON }}" \ - --argjson vtResults "${{ needs.virusTotal-analysis.outputs.vtResultsJSON }}" \ - --arg vtScanUrl "${{ needs.virusTotal-analysis.outputs.vtScanUrl }}" \ + jq --argjson codeQLwarnings '${{ needs.codeQL-analysis.outputs.warningsJSON }}' \ + --argjson codeQLerrors '${{ needs.codeQL-analysis.outputs.errorsJSON }}' \ + --argjson vtResults '${{ needs.virusTotal-analysis.outputs.vtResultsJSON }}' \ + --arg vtScanUrl '${{ needs.virusTotal-analysis.outputs.vtScanUrl }}' \ '. + { vtScanUrl: $vtScanUrl, scanResults: { From 3b8f2d977cf5e97c6101d4d9258c3af1dea4f004 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 21 Aug 2025 12:47:34 +1000 Subject: [PATCH 14/25] fixup quotations --- .github/workflows/checkAndSubmitAddonMetadata.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index ab0346f20c1..f9f84b1ffcc 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -289,9 +289,9 @@ jobs: '. + { vtScanUrl: $vtScanUrl, scanResults: { - codeQL-warnings: $codeQLwarnings, - codeQL-errors: $codeQLerrors, - virusTotal: $vtResults + "codeQL-warnings": $codeQLwarnings, + "codeQL-errors": $codeQLerrors, + "virusTotal": $vtResults } }' \ addons/${{ needs.getAddonId.outputs.addonFileName }} > tmp.json From d5ff0a5b548dc221fc4602b25cab9c69ddee0669 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 21 Aug 2025 12:50:57 +1000 Subject: [PATCH 15/25] require scan results for merge to master --- .github/workflows/checkAndSubmitAddonMetadata.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index f9f84b1ffcc..285c430f375 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -316,8 +316,8 @@ jobs: run: echo "Manual approval performed" mergeToMaster: - needs: [getAddonId, createPullRequest, requireManualApproval] - if: ${{ always() && (needs.requireManualApproval.result == 'success' || needs.requireManualApproval.result == 'skipped') }} + needs: [getAddonId, commitScanResults, createPullRequest, requireManualApproval] + if: ${{ always() && needs.commitScanResults.result == 'success' && (needs.requireManualApproval.result == 'success' || needs.requireManualApproval.result == 'skipped') }} permissions: contents: write pull-requests: write From c3702d1762a313195f19e3be62e90e9e3b305365 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 21 Aug 2025 13:36:19 +1000 Subject: [PATCH 16/25] fix path --- .github/workflows/checkAndSubmitAddonMetadata.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index 285c430f375..8b95b1b22f3 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -294,8 +294,8 @@ jobs: "virusTotal": $vtResults } }' \ - addons/${{ needs.getAddonId.outputs.addonFileName }} > tmp.json - mv tmp.json addons/${{ needs.getAddonId.outputs.addonFileName }} + ${{ needs.getAddonId.outputs.addonFileName }} > tmp.json + mv tmp.json ${{ needs.getAddonId.outputs.addonFileName }} - name: Commit add-on metadata run: | git add ${{ needs.getAddonId.outputs.addonFileName }} From fc55140a6ccf53eed6cad7ba0071d4b2c144fc19 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 21 Aug 2025 16:57:20 +1000 Subject: [PATCH 17/25] scan with codeql --- .github/workflows/virusScanAllAddons.yml | 106 ++++++++++++++++++++--- 1 file changed, 95 insertions(+), 11 deletions(-) diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index 4c1b5746e4f..41af06e132b 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -11,19 +11,18 @@ on: - cron: '0 18 * * *' workflow_dispatch: +env: + BRANCH_NAME: addScanResults${{ github.run_number }} + jobs: virusTotal-analysis: runs-on: windows-latest - strategy: - matrix: - python-version: [ 3.13 ] permissions: contents: write pull-requests: write env: VT_API_KEY: ${{ secrets.VT_API_KEY }} VT_API_LIMIT: ${{ vars.VT_API_LIMIT }} - BRANCH_NAME: addVTresults${{ github.run_number }} BATCH_SIZE: 10 steps: - name: Checkout repository @@ -43,7 +42,7 @@ jobs: shell: bash run: | for file in ./addons/*/*.json; do - if (jq -r '.scanResults | .virusTotal' "$file" | grep -q 'null\|""'); then + if (jq -r '.scanResults.virusTotal' "$file" | grep -q '^null\|""$'); then echo "$file" >> addonsWithoutVT.txt fi done @@ -57,7 +56,7 @@ jobs: const fs = require('fs') const addonsWithoutVT = fs.readFileSync('addonsWithoutVT.txt', 'utf-8').split('\n').filter(Boolean) setVirusTotalAnalysisStatus({core}, addonsWithoutVT.slice(0, ${{ env.BATCH_SIZE }})) - - name: Create PR for updated VT urls + - name: Push updated VT urls shell: bash run: | git add addons @@ -66,11 +65,96 @@ jobs: git commit -m "Add VirusTotal results" git pull --rebase git push --set-upstream origin ${{ env.BRANCH_NAME }} + env: + GH_TOKEN: ${{ github.token }} + + codeQL-analysis-prep: + runs-on: windows-latest + outputs: + addonsWithoutCodeQL: ${{ steps.getAddonsWithoutCodeQL.outputs.addonsWithoutCodeQL }} + env: + BATCH_SIZE: 10 + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + ref: ${{ env.BRANCH_NAME }} + - name: Install Node.js + uses: actions/setup-node@v4 + - name: Install npm dependencies + run: npm install uuid + - name: Get add-on filenames without scan results + shell: bash + run: | + for file in ./addons/*/*.json; do + if (jq -r '.scanResults | ."codeQL-errors"' "$file" | grep -q 'null\|""'); then + echo "$file" >> addonsWithoutCodeQL.txt + fi + done + wc -l addonsWithoutCodeQL.txt | awk '{print "Total add-ons without scan results: " $1}' + # take the first batch of lines + head -n ${{ env.BATCH_SIZE }} addonsWithoutCodeQL.txt > addonsWithoutCodeQL_batch.txt + # Create JSON list of file names, single line string + + jq -R . < addonsWithoutCodeQL_batch.txt | jq -s -c . > addonsWithoutCodeQL.json + # Store as GitHub output + echo "addonsWithoutCodeQL=$(cat addonsWithoutCodeQL.json)" >> $GITHUB_OUTPUT + + codeQL-analysis: + needs: codeQL-analysis-prep + runs-on: windows-latest + permissions: + contents: write + strategy: + matrix: + addonFileName: ${{ fromJson(needs.codeQL-analysis-prep.outputs.addonsWithoutCodeQL) }} + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + ref: ${{ env.BRANCH_NAME }} + - name: Set CodeQL analysis status + id: analysis + uses: ./.github/workflows/codeql-analysis.yml + with: + addonFileName: ${{ matrix.addonFileName }} + branchName: ${{ env.BRANCH_NAME }} + - name: Collate analysis results into add-on metadata + run: | + jq --argjson codeQLwarnings '${{ steps.analysis.outputs.warningsJSON }}' \ + --argjson codeQLerrors '${{ steps.analysis.outputs.errorsJSON }}' \ + '. + { + scanResults: { + "codeQL-warnings": $codeQLwarnings, + "codeQL-errors": $codeQLerrors + } + }' \ + ${{ matrix.addonFileName }} > tmp.json + mv tmp.json ${{ matrix.addonFileName }} + - name: Commit add-on metadata + run: | + git add ${{ matrix.addonFileName }} + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git commit -m "Add codeQL analysis results for ${{ matrix.addonFileName }}" + git pull --rebase + git push --set-upstream origin ${{ env.branchName }} + + pull-request: + needs: codeQL-analysis + runs-on: windows-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Open pr and merge + shell: bash + run: | gh pr create \ - --title "Add VirusTotal results" \ - --base ${{ github.ref }} \ - --head ${{ env.BRANCH_NAME }} \ - --body "Add VirusTotal results to add-ons" - gh pr merge --merge "${{ env.BRANCH_NAME }}" + --title "Add scanning results" \ + --base ${{ github.ref }} \ + --head ${{ env.BRANCH_NAME }} \ + --body "Add scanning results to add-ons" + gh pr merge --merge "${{ env.BRANCH_NAME }}" env: GH_TOKEN: ${{ github.token }} From 486e16eef5cda74627f3dc466df003378c726db6 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 21 Aug 2025 17:00:42 +1000 Subject: [PATCH 18/25] fix syntax --- .github/workflows/virusScanAllAddons.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index 41af06e132b..c6a70c0b32a 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -1,4 +1,4 @@ -name: Scan a batch of submitted add-ons with Virus Total +name: Scan a batch of add-ons on: # Every day at 6pm UTC. @@ -140,7 +140,7 @@ jobs: git pull --rebase git push --set-upstream origin ${{ env.branchName }} - pull-request: + pull-request: needs: codeQL-analysis runs-on: windows-latest permissions: From d84eff118db3bc01eac81412aee25c1bad22e375 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 21 Aug 2025 17:05:50 +1000 Subject: [PATCH 19/25] fix ref dependencies --- .github/workflows/virusScanAllAddons.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index c6a70c0b32a..093d662cd24 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -78,7 +78,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v5 with: - ref: ${{ env.BRANCH_NAME }} + ref: ${{ github.ref }} - name: Install Node.js uses: actions/setup-node@v4 - name: Install npm dependencies @@ -101,7 +101,8 @@ jobs: echo "addonsWithoutCodeQL=$(cat addonsWithoutCodeQL.json)" >> $GITHUB_OUTPUT codeQL-analysis: - needs: codeQL-analysis-prep + # Require virusTotal analysis to run first to prevent merge conflicts to add-on metadata + needs: [codeQL-analysis-prep, virusTotal-analysis] runs-on: windows-latest permissions: contents: write From bf92d6f23cbe9176f195fd829de3179acf326d89 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 21 Aug 2025 17:19:59 +1000 Subject: [PATCH 20/25] fix pulls --- .github/workflows/checkAndSubmitAddonMetadata.yml | 1 - .github/workflows/virusScanAllAddons.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index 8b95b1b22f3..65353af3c71 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -436,7 +436,6 @@ jobs: git add . git commit -m "update discussion URL" git branch -u origin/master - git pull git push call-workflow: diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index 093d662cd24..a62572819f8 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -63,7 +63,6 @@ jobs: git config user.name "github-actions" git config user.email "github-actions@github.com" git commit -m "Add VirusTotal results" - git pull --rebase git push --set-upstream origin ${{ env.BRANCH_NAME }} env: GH_TOKEN: ${{ github.token }} From 6cbd338dce6d5cf582a3113762e23fb3adbe3028 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 21 Aug 2025 17:32:17 +1000 Subject: [PATCH 21/25] Fix missing ref --- .github/workflows/virusScanAllAddons.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index a62572819f8..2d5e8224635 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -84,6 +84,7 @@ jobs: run: npm install uuid - name: Get add-on filenames without scan results shell: bash + id: getAddonsWithoutCodeQL run: | for file in ./addons/*/*.json; do if (jq -r '.scanResults | ."codeQL-errors"' "$file" | grep -q 'null\|""'); then From 8648ca24ad7229cbd5217c40072db5a2aa448f56 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 22 Aug 2025 11:59:37 +1000 Subject: [PATCH 22/25] Remove codeQL --- .github/workflows/virusScanAllAddons.yml | 76 +----------------------- 1 file changed, 1 insertion(+), 75 deletions(-) diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index 2d5e8224635..c3de284dda6 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -67,82 +67,8 @@ jobs: env: GH_TOKEN: ${{ github.token }} - codeQL-analysis-prep: - runs-on: windows-latest - outputs: - addonsWithoutCodeQL: ${{ steps.getAddonsWithoutCodeQL.outputs.addonsWithoutCodeQL }} - env: - BATCH_SIZE: 10 - steps: - - name: Checkout repository - uses: actions/checkout@v5 - with: - ref: ${{ github.ref }} - - name: Install Node.js - uses: actions/setup-node@v4 - - name: Install npm dependencies - run: npm install uuid - - name: Get add-on filenames without scan results - shell: bash - id: getAddonsWithoutCodeQL - run: | - for file in ./addons/*/*.json; do - if (jq -r '.scanResults | ."codeQL-errors"' "$file" | grep -q 'null\|""'); then - echo "$file" >> addonsWithoutCodeQL.txt - fi - done - wc -l addonsWithoutCodeQL.txt | awk '{print "Total add-ons without scan results: " $1}' - # take the first batch of lines - head -n ${{ env.BATCH_SIZE }} addonsWithoutCodeQL.txt > addonsWithoutCodeQL_batch.txt - # Create JSON list of file names, single line string - - jq -R . < addonsWithoutCodeQL_batch.txt | jq -s -c . > addonsWithoutCodeQL.json - # Store as GitHub output - echo "addonsWithoutCodeQL=$(cat addonsWithoutCodeQL.json)" >> $GITHUB_OUTPUT - - codeQL-analysis: - # Require virusTotal analysis to run first to prevent merge conflicts to add-on metadata - needs: [codeQL-analysis-prep, virusTotal-analysis] - runs-on: windows-latest - permissions: - contents: write - strategy: - matrix: - addonFileName: ${{ fromJson(needs.codeQL-analysis-prep.outputs.addonsWithoutCodeQL) }} - steps: - - name: Checkout repository - uses: actions/checkout@v5 - with: - ref: ${{ env.BRANCH_NAME }} - - name: Set CodeQL analysis status - id: analysis - uses: ./.github/workflows/codeql-analysis.yml - with: - addonFileName: ${{ matrix.addonFileName }} - branchName: ${{ env.BRANCH_NAME }} - - name: Collate analysis results into add-on metadata - run: | - jq --argjson codeQLwarnings '${{ steps.analysis.outputs.warningsJSON }}' \ - --argjson codeQLerrors '${{ steps.analysis.outputs.errorsJSON }}' \ - '. + { - scanResults: { - "codeQL-warnings": $codeQLwarnings, - "codeQL-errors": $codeQLerrors - } - }' \ - ${{ matrix.addonFileName }} > tmp.json - mv tmp.json ${{ matrix.addonFileName }} - - name: Commit add-on metadata - run: | - git add ${{ matrix.addonFileName }} - git config user.name "github-actions" - git config user.email "github-actions@github.com" - git commit -m "Add codeQL analysis results for ${{ matrix.addonFileName }}" - git pull --rebase - git push --set-upstream origin ${{ env.branchName }} - pull-request: - needs: codeQL-analysis + needs: virusTotal-analysis runs-on: windows-latest permissions: contents: write From fcd0096331df35889705a06398d0e6c418422d43 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 22 Aug 2025 12:10:27 +1000 Subject: [PATCH 23/25] checkout repo --- .github/workflows/virusScanAllAddons.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/virusScanAllAddons.yml b/.github/workflows/virusScanAllAddons.yml index c3de284dda6..d47769f0ab4 100644 --- a/.github/workflows/virusScanAllAddons.yml +++ b/.github/workflows/virusScanAllAddons.yml @@ -74,6 +74,10 @@ jobs: contents: write pull-requests: write steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + ref: ${{ env.BRANCH_NAME }} - name: Open pr and merge shell: bash run: | From 98c5e32ac7da8a4995bfcfb800441eb298729089 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Tue, 2 Sep 2025 12:41:22 +1000 Subject: [PATCH 24/25] review fixes --- .github/workflows/checkAndSubmitAddonMetadata.yml | 8 ++++---- .github/workflows/codeql-analysis.yml | 4 ++-- .github/workflows/virusTotalAnalysis.js | 9 +++------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/.github/workflows/checkAndSubmitAddonMetadata.yml b/.github/workflows/checkAndSubmitAddonMetadata.yml index 65353af3c71..17e7c8a0b13 100644 --- a/.github/workflows/checkAndSubmitAddonMetadata.yml +++ b/.github/workflows/checkAndSubmitAddonMetadata.yml @@ -282,15 +282,15 @@ jobs: ref: ${{ env.branchName }} - name: Collate analysis results into add-on metadata run: | - jq --argjson codeQLwarnings '${{ needs.codeQL-analysis.outputs.warningsJSON }}' \ - --argjson codeQLerrors '${{ needs.codeQL-analysis.outputs.errorsJSON }}' \ + jq --argjson codeQLWarnings '${{ needs.codeQL-analysis.outputs.warningsJSON }}' \ + --argjson codeQLErrors '${{ needs.codeQL-analysis.outputs.errorsJSON }}' \ --argjson vtResults '${{ needs.virusTotal-analysis.outputs.vtResultsJSON }}' \ --arg vtScanUrl '${{ needs.virusTotal-analysis.outputs.vtScanUrl }}' \ '. + { vtScanUrl: $vtScanUrl, scanResults: { - "codeQL-warnings": $codeQLwarnings, - "codeQL-errors": $codeQLerrors, + "codeQL-warnings": $codeQLWarnings, + "codeQL-errors": $codeQLErrors, "virusTotal": $vtResults } }' \ diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b74b72ce48d..57287f06250 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -12,10 +12,10 @@ on: outputs: warningsJSON: description: "The JSON from CodeQL warnings" - value: ${{ jobs.analyzeExcludingWarnings.outputs.codeQLResults }} + value: ${{ jobs.analyze.outputs.codeQLResults }} errorsJSON: description: "The JSON from CodeQL errors" - value: ${{ jobs.analyze.outputs.codeQLResults }} + value: ${{ jobs.analyzeExcludingWarnings.outputs.codeQLResults }} jobs: analyzeExcludingWarnings: diff --git a/.github/workflows/virusTotalAnalysis.js b/.github/workflows/virusTotalAnalysis.js index 135890e8a45..cc953e6bdbc 100644 --- a/.github/workflows/virusTotalAnalysis.js +++ b/.github/workflows/virusTotalAnalysis.js @@ -8,8 +8,7 @@ function writeVTScanUrl({core}, metadataFile, addonMetadata) { const vtScanUrl = `https://www.virustotal.com/gui/file/${addonMetadata.sha256}`; if (core._isSingleFileAnalysis) { core.setOutput("vtScanUrl", vtScanUrl); - } - else { + } else { addonMetadata.vtScanUrl = vtScanUrl; stringified = JSON.stringify(addonMetadata, null, "\t"); fs.writeFileSync(metadataFile, stringified + "\n"); @@ -45,8 +44,7 @@ function getVirusTotalAnalysis({core}, addonMetadata, metadataFile) { const malicious = stats.malicious; if (core._isSingleFileAnalysis) { core.setOutput("vtResults", vtData); - } - else { + } else { if (addonMetadata.scanResults === undefined) { addonMetadata.scanResults = {}; } @@ -56,8 +54,7 @@ function getVirusTotalAnalysis({core}, addonMetadata, metadataFile) { } if (malicious === 0) { core.info(`VirusTotal analysis succeeded for ${metadataFile}`); - } - else if (core._isSingleFileAnalysis) { + } else if (core._isSingleFileAnalysis) { core.setFailed(`VirusTotal analysis failed for ${metadataFile}`); } }); From 43e99306cbec2d1100d085f023744e048184cd21 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Fri, 5 Sep 2025 15:32:55 +1000 Subject: [PATCH 25/25] update docs --- docs/dev/submissionReview.md | 50 ++++++++++++++++-------------- docs/submitters/submissionGuide.md | 7 +++++ 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/docs/dev/submissionReview.md b/docs/dev/submissionReview.md index d83e5831bf5..fc025033815 100644 --- a/docs/dev/submissionReview.md +++ b/docs/dev/submissionReview.md @@ -1,5 +1,7 @@ +# Submission review processes + +## Approving an author to submit to a particular add-on ID for the first time -### Approving an author to submit to a particular add-on ID for the first time When a GitHub user submits a particular add-on for the first time, the submission is blocked pending initial review from NV Access. This is to confirm that the GitHub user has authorisation to submit the add-on from the add-on maintainers. In some cases, 2 separate add-on maintainers may want to lay claim to a single "add-on ID". @@ -8,33 +10,35 @@ It would be misleading and potentially risky to be encouraged to update to a for See [the submission guide](../submitters/submissionGuide.md#approval-process) for further reasoning behind this. This registration process ensures a specific add-on ID is only submitted by the same group of authorised maintainers. -#### Process +### Process for first time submissions + The process for reviewing pending first submissions is as follows: 1. A Pull Request named "Add `GitHubName` as an approved submitter for `addonId`" will be waiting on review. - - Example: https://github.com/nvaccess/addon-datastore/pull/2674 + * Example: 1. Open the referenced issue 1. Check the source code link in the referenced issue. - - Ensure the submitter matches the repository ownership, or the submitter is a core maintainer for the project. + * Ensure the submitter matches the repository ownership, or the submitter is a core maintainer for the project. If this is not the case, tag the core maintainer in the submission to confirm they give permission for the submission. - - Check for any obvious red flags with the repository i.e. it doesn't look structured as an add-on, inappropriate content in the readme, author and code only been around for a few days + * Check for any obvious red flags with the repository i.e. it doesn't look structured as an add-on, inappropriate content in the readme, author and code only been around for a few days 1. If it is clear that the submitter has permission to submit the add-on, merge the approval PR. 1. Relabel the original issue with `autoSubmissionFromIssue` - - i.e. remove the label, save, add the label back, save. - - This will resubmit the issue. - -#### Handling known issues - -##### "Create branch" fails -If an issue is mistakenly relabelled twice, the subsequent action may fail at the "Create branch" step. -To fix this: -1. Go to the GitHub action failure and identify the name of the branch where "Create branch" is failing. -1. Go to the [branches for the repository](https://github.com/nvaccess/addon-datastore/branches) and delete the branch. -1. Check if the initial issue has been successfully submitted already. - - The summary of the GitHub action failure should have a message like "Triggered via issue `x days ago` `@gitHubUserWhoSubmittedOrLabelledTheIssue` labeled `#issueNum` `commitRef`" - - Confirm that the issue was closed successfully with a matching merged PR - - Confirm that the add-on version (add-on id and version number) [exists in the repository](https://github.com/nvaccess/addon-datastore/tree/master/addons) -1. If the issue has been submitted correctly, no further action is required. -1. If the issue has not been submitted correctly, relabel the original issue with `autoSubmissionFromIssue` - - i.e. remove the label, save, add the label back, save. - - This will resubmit the issue. + * i.e. remove the label, save, add the label back, save. + * This will resubmit the issue. + +## Approving an add-on which was flagged as malicious + +An add-on may be flagged as malicious by CodeQL or VirusTotal. +If this happens, the submission process will be held, pending approval from NV Access. +This is done using a [deployment environment](https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/review-deployments). + +### Process for flagged add-ons + +1. A comment should appear on the GitHub issue with information on why the add-on was flagged. + * For CodeQL results, review the SARIF file. + * For VirusTotal results, review the VirusTotal link. +1. Consider if the flagged content is a false positive. +This may require discussion within NV Access or with the add-on contributor. +1. Go to the failed submission in GitHub Actions. +Approve or deny the deployment. +If the deployment review request has expired, re-run the job. diff --git a/docs/submitters/submissionGuide.md b/docs/submitters/submissionGuide.md index eda943cce12..c54e07bf79d 100644 --- a/docs/submitters/submissionGuide.md +++ b/docs/submitters/submissionGuide.md @@ -22,6 +22,7 @@ If there are validation errors, they will be commented on the pull request. Otherwise, the pull request will be merged, the issue will be closed and the add-on will become available in the Add-on Store. ## Approval process + Publishers must be approved to submit add-ons, on a per add-on basis. If you do not maintain the submitted add-on's repository, it is expected that you have authorisation to publish the add-on from the authors. @@ -33,21 +34,27 @@ Submitters which abuse the submission process will have their submitter approval Please report any issues with submitted add-ons to . ## Steps to submit an add-on + 1. Select ["Add-on registration" from the new issue options](https://github.com/nvaccess/addon-datastore/issues/new/choose). 1. Fill out and submit the issue form. This will create an issue with a summary of your submission, and generate a pull request to submit your add-on to the store. 1. If this is your first submission of this add-on, [manual approval](#approval-process) will be required to be added to the approved submitters list for the add-on. You do not need to do anything if you are the maintainer of the add-on you submitted. +Please wait for an NV Access staff member to review the submission. 1. Automated checks are ran on the pull request to validate the submission. Refer to [addon-datastore-validation](https://github.com/nvaccess/addon-datastore-validation) for more information on automated checks. 1. If the checks fail, a comment should be added to the issue outlining the failure. To address the issues, resubmit the issue form. You may need to also update your add-on manifest. Descriptions for the fields of the JSON schema can be found in [jsonMetadata.md](./jsonMetadata.md). +1. The checks may fail due to code being flagged as malicious. +Please review the flagged content and consider fixing them or commenting why they are a false positive. +An NV Access staff will review the submission and consider accepting if they believe it is a false positive. 1. If the checks pass, the pull request should be merged automatically. The add-on should soon become available in the store. ## Registering an add-on in the translation system + Optional. Some authors may wish to include their add-on in the translations system. To do this, follow the steps to register the add-on in [mrconfig](https://github.com/nvaccess/mrconfig/blob/master/readme.md#steps-for-addon-authors).