From cbabd6d58734a6d090982f17b49250066e5e1799 Mon Sep 17 00:00:00 2001 From: Daniel Persson <17487347+saligiad@users.noreply.github.com> Date: Tue, 4 Aug 2026 13:47:44 -0700 Subject: [PATCH 1/5] CIS-3816 Audit workflow Create a shared workflow to `npm audit fix`: * Creates branch, commits the dependency changes, and opens a PR * Parameterizes branch name, commit title, and cleanup behavior for different use cases * By default, cleans up branches with the same name and associated PRs Currently, workflow fails if `npm audit fix` returns non-zero exit code - meaning PRs will not be created for breaking changes or conflicts in dependency resolution. --- .github/workflows/node-audit.yaml | 102 ++++++++++++++++++++++++++++++ README.md | 23 +++++++ 2 files changed, 125 insertions(+) create mode 100644 .github/workflows/node-audit.yaml diff --git a/.github/workflows/node-audit.yaml b/.github/workflows/node-audit.yaml new file mode 100644 index 0000000..98188ec --- /dev/null +++ b/.github/workflows/node-audit.yaml @@ -0,0 +1,102 @@ +name: Node.js tests + +on: + workflow_call: + inputs: + node_version: + description: Node.js version to use with the setup-node action + type: string + required: true + branch_name: + description: Name for the new PR branch + type: string + required: false + default: chore/node-audit + commit_title: + description: Text for the title line of the git commit + type: string + required: false + default: 'chore: Node security update' + cleanup_previous: + description: Whether to cleanup unresolved PR/branch and start over + type: boolean + required: false + default: true + +jobs: + run-node-audit: + name: Run Node.js security update + runs-on: ubuntu-latest + permissions: + pull-requests: write + contents: read + steps: + - name: Check out repository + uses: actions/checkout@v7 + + - name: Set up Node.js + uses: actions/setup-node@v6 + with: + node-version: ${{ inputs.node_version }} + cache: npm + + - name: Fix Node.js vulnerabilities + id: audit-step + run: | + echo "AUDIT_REPORT<> "$GITHUB_OUTPUT" + npm audit fix &>> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + if [ -n "$(git status --porcelain)" ]; then + echo "CHANGED=true" >> "$GITHUB_OUTPUT" + else + echo "CHANGED=false" >> "$GITHUB_OUTPUT" + fi + + - name: Set up Git + if: steps.audit-step.outputs.CHANGED == 'true' + run: | + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + + - name: Clean up previous branch/PR + if: ${{ inputs.cleanup_previous }} + env: + BRANCH: ${{ inputs.branch_name}} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Clean up PR and remote branch + PR_NUMBER=$(gh pr list --head "$BRANCH" --state open --json number --jq '.[0].number') + if [ -n "$PR_NUMBER" ]; then + gh pr close "$PR_NUMBER" + git push origin --delete "$BRANCH" + git fetch --prune + fi + # Clean up local branch + if [ -n "$(git branch --list "$BRANCH")" ]; then + git branch -D "$BRANCH" + fi + + - name: Establish branch and create commit + if: steps.audit-step.outputs.CHANGED == 'true' + env: + COMMIT_TITLE: ${{ inputs.commit_title }} + BRANCH_NAME: ${{ inputs.branch_name }} + run: | + git checkout -b "$BRANCH_NAME" + git add package.json package-lock.json + git commit -m "$COMMIT_TITLE" -m 'Ran `npm audit fix` to resolve Node.js vulnerabilities' + git push -u origin "$BRANCH_NAME" + + - name: Create PR for new branch + if: steps.audit-step.outputs.CHANGED == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRANCH_NAME: ${{ inputs.branch_name }} + AUDIT_REPORT: ${{ steps.audit-step.outputs.AUDIT_REPORT }} + BASE_BRANCH: ${{ github.ref_name }} + run: | + gh pr create \ + --title "Chore: Node Security Audit" \ + --body "$AUDIT_REPORT" \ + --base "$BASE_BRANCH" \ + --head "$BRANCH_NAME" diff --git a/README.md b/README.md index 0e43c91..3634520 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,29 @@ See `java-build.yaml` for a similar workflow that publishes the build artifacts --- +### `node-audit.yaml` + +Fixes security vulnerabilities in Node.js dependencies and creates a PR using a new branch. This pipeline uses the `node-test.yaml` workflow. + +This workflow may fail for a couple different reasons: + +- Errors generated by `npm audit fix`, possibly to due breaking dependency updates or version conflicts +- If `cleanup_previous=false`, the workflow fails if `branch_name` correspond to an existing branch + +**Trigger:** `workflow_call` + +**Inputs:** +| Input | Type | Required | Description | +|-------|------|----------|-------------| +| `node_version` | string | yes | Node.js version for `setup-node` | +| `branch_name` | string | yes | Name for the PR HEAD branch. | +| `commit_title` | string | no | Title for the git commit. | +| `cleanup_previous` | boolean | no | Whether to delete unresolved PR and/or lingering branch. | + +**Required secrets:** `GITHUB_TOKEN` + +--- + ### `node-test.yaml` Runs Node.js tests. Your `package.json` file must have a script named `test:ci` that runs your test suite. From 3bc94c9b0dbbaf7bec74d5cdf50e3b44333b2031 Mon Sep 17 00:00:00 2001 From: Daniel Persson <17487347+saligiad@users.noreply.github.com> Date: Tue, 4 Aug 2026 13:54:15 -0700 Subject: [PATCH 2/5] CIS-3816 Update changelog Reference new workflow file in CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a8a856..66357d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add workflow that runs Node.js tests - Add infrastructure for container image builds (RFS-256) - Add a workflow that builds the Maven project without publishing (CIS-3773) +- Added a workflow to audit and fix Node.js dependencies (CIS-3816) ### Changed From d683549fb1b724665982fc46998aa8255efd38ae Mon Sep 17 00:00:00 2001 From: Daniel Persson <17487347+saligiad@users.noreply.github.com> Date: Tue, 4 Aug 2026 13:57:59 -0700 Subject: [PATCH 3/5] CIS-3816 Add write Adds `content: write` to the job permissions, allowing the workflow to push branch deletion to the main repo. --- .github/workflows/node-audit.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/node-audit.yaml b/.github/workflows/node-audit.yaml index 98188ec..6e4145b 100644 --- a/.github/workflows/node-audit.yaml +++ b/.github/workflows/node-audit.yaml @@ -30,6 +30,7 @@ jobs: permissions: pull-requests: write contents: read + contents: write steps: - name: Check out repository uses: actions/checkout@v7 From e4422ebe0b87e786e88b4184c4d15786b02e91e1 Mon Sep 17 00:00:00 2001 From: Daniel Persson <17487347+saligiad@users.noreply.github.com> Date: Tue, 4 Aug 2026 22:41:39 -0700 Subject: [PATCH 4/5] CIS-3816 PR feedback Incorporate feedback from the PR: * Simplify commit message default * Remove `cleanup_previous` flag, given absense of compelling use case --- .github/workflows/node-audit.yaml | 8 +------- README.md | 6 +----- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/.github/workflows/node-audit.yaml b/.github/workflows/node-audit.yaml index 6e4145b..ee2369c 100644 --- a/.github/workflows/node-audit.yaml +++ b/.github/workflows/node-audit.yaml @@ -16,12 +16,7 @@ on: description: Text for the title line of the git commit type: string required: false - default: 'chore: Node security update' - cleanup_previous: - description: Whether to cleanup unresolved PR/branch and start over - type: boolean - required: false - default: true + default: 'Node security update' jobs: run-node-audit: @@ -60,7 +55,6 @@ jobs: git config --global user.name "github-actions[bot]" - name: Clean up previous branch/PR - if: ${{ inputs.cleanup_previous }} env: BRANCH: ${{ inputs.branch_name}} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 3634520..a94c2cf 100644 --- a/README.md +++ b/README.md @@ -119,10 +119,7 @@ See `java-build.yaml` for a similar workflow that publishes the build artifacts Fixes security vulnerabilities in Node.js dependencies and creates a PR using a new branch. This pipeline uses the `node-test.yaml` workflow. -This workflow may fail for a couple different reasons: - -- Errors generated by `npm audit fix`, possibly to due breaking dependency updates or version conflicts -- If `cleanup_previous=false`, the workflow fails if `branch_name` correspond to an existing branch +This workflow will fail if `npm audit fix` generates any errors, such as breaking dependency updates or version conflicts. **Trigger:** `workflow_call` @@ -132,7 +129,6 @@ This workflow may fail for a couple different reasons: | `node_version` | string | yes | Node.js version for `setup-node` | | `branch_name` | string | yes | Name for the PR HEAD branch. | | `commit_title` | string | no | Title for the git commit. | -| `cleanup_previous` | boolean | no | Whether to delete unresolved PR and/or lingering branch. | **Required secrets:** `GITHUB_TOKEN` From eccedb456f31f1e63820f05a4c80abe2183bb03c Mon Sep 17 00:00:00 2001 From: Daniel Persson <17487347+saligiad@users.noreply.github.com> Date: Tue, 4 Aug 2026 23:41:06 -0700 Subject: [PATCH 5/5] CIS-3816 Git setup Ensure that git user/email are setup, regardless of whether files have changed, because the workflow will always attempt to cleanup previous PRs. --- .github/workflows/node-audit.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/node-audit.yaml b/.github/workflows/node-audit.yaml index ee2369c..89fc233 100644 --- a/.github/workflows/node-audit.yaml +++ b/.github/workflows/node-audit.yaml @@ -49,7 +49,6 @@ jobs: fi - name: Set up Git - if: steps.audit-step.outputs.CHANGED == 'true' run: | git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --global user.name "github-actions[bot]"