From 1e09fa169f4c6a5ae7643a139ebbeb83ebd65915 Mon Sep 17 00:00:00 2001 From: Kiro Agent <244629292+kiro-agent@users.noreply.github.com> Date: Mon, 8 Jun 2026 14:05:31 +0000 Subject: [PATCH 1/3] ci: harden pre-merge checks and supply chain - add CodeQL workflow (javascript-typescript + actions) for parity with the plugins repo security scanning - add commitlint job validating PR commits (Conventional Commits) - add npm audit job (high/critical severity gate) - set top-level least-privilege permissions and PR concurrency cancellation on the CI workflow - drop the redundant build in the test job (pretest already builds) - pin remaining release.yml actions to commit SHAs - track npm updates via dependabot Co-authored-by: Jack Granatowski --- .github/dependabot.yml | 5 ++++ .github/workflows/ci.yml | 52 ++++++++++++++++++++++++++++++++++- .github/workflows/codeql.yml | 39 ++++++++++++++++++++++++++ .github/workflows/release.yml | 10 +++---- 4 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ca79ca5b..8b2c4c07 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,3 +4,8 @@ updates: directory: / schedule: interval: weekly + + - package-ecosystem: npm + directory: / + schedule: + interval: weekly diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a949f581..86d3116c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,16 @@ on: branches: [main] pull_request: +# Least-privilege default for every job; widen per-job only when needed. +permissions: + contents: read + +# Cancel superseded runs on the same ref (e.g. rapid pushes to a PR) so CI +# only spends minutes on the newest commit. Pushes to main run to completion. +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + jobs: lint: name: Lint CSS @@ -20,6 +30,29 @@ jobs: - run: npm ci - run: npm run lint:css + commitlint: + name: Lint commit messages + runs-on: ubuntu-latest + # Commit-message linting only makes sense against a PR's commit range. + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + # Full history so commitlint can walk base..head. + fetch-depth: 0 + persist-credentials: false + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22 + cache: npm + - run: npm ci + - name: Validate PR commits against Conventional Commits + run: >- + npx --no -- commitlint + --from ${{ github.event.pull_request.base.sha }} + --to ${{ github.event.pull_request.head.sha }} + --verbose + build: name: Build bundle runs-on: ubuntu-latest @@ -56,6 +89,22 @@ jobs: - run: node scripts/check-artifacts.js --check - run: node scripts/check-version-sync.js + dependency-audit: + name: Dependency vulnerability audit + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22 + cache: npm + - run: npm ci + # Fail only on high/critical advisories so routine low-severity noise + # doesn't block merges. Tune the threshold as the project matures. + - run: npm audit --audit-level=high + test: name: Regression tests runs-on: ubuntu-latest @@ -68,6 +117,7 @@ jobs: node-version: 22 cache: npm - run: npm ci - - run: npm run build + # `npm test` runs the `pretest` hook (build + unit tests) before Playwright, + # so an explicit build step here would just build twice. - run: npx playwright install --with-deps chromium firefox webkit - run: npm test diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..630435d3 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,39 @@ +name: CodeQL + +# Static security analysis for the build/test/docs tooling (scripts/, tests/) +# and the workflow definitions themselves. Mirrors the SLASHED-Plugins setup so +# both repositories get the same security coverage. + +on: + push: + branches: [main] + pull_request: + schedule: + - cron: '0 8 * * 1' + +permissions: + contents: read + actions: read + security-events: write + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + language: [javascript-typescript, actions] + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - uses: github/codeql-action/init@b0c4fd77f6c559021d78430ec4d0d169ae74a4eb # v3 + with: + languages: ${{ matrix.language }} + queries: security-extended + + - uses: github/codeql-action/analyze@b0c4fd77f6c559021d78430ec4d0d169ae74a4eb # v3 + with: + category: /language:${{ matrix.language }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 244967a1..5e8f56ae 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,10 +21,10 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: actions/setup-node@v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: 22 cache: npm @@ -93,7 +93,7 @@ jobs: echo "notes<> "$GITHUB_OUTPUT" echo "$NOTES" >> "$GITHUB_OUTPUT" echo "EOF" >> "$GITHUB_OUTPUT" - - uses: softprops/action-gh-release@v3 + - uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3 with: tag_name: ${{ steps.version.outputs.tag }} body: ${{ steps.changelog.outputs.notes }} @@ -151,12 +151,12 @@ jobs: contents: write steps: - name: Checkout main - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: main fetch-depth: 1 persist-credentials: false - - uses: actions/setup-node@v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: 22 - name: Determine version From 0922bbaf55136441192f888f8323631142d1f395 Mon Sep 17 00:00:00 2001 From: Kiro Agent <244629292+kiro-agent@users.noreply.github.com> Date: Mon, 8 Jun 2026 15:08:48 +0000 Subject: [PATCH 2/3] ci: drop npm cache from release and publish-dist workflows Pre-empt the cache-poisoning class flagged by zizmor on the plugins repo: a poisoned dependency cache could be baked into the published GitHub Release assets or the CDN-served dist branch. These workflows now fetch dependencies fresh with integrity verification. CI keeps its cache. --- .github/workflows/publish-dist.yml | 4 +++- .github/workflows/release.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-dist.yml b/.github/workflows/publish-dist.yml index da0a6df0..7332d2af 100644 --- a/.github/workflows/publish-dist.yml +++ b/.github/workflows/publish-dist.yml @@ -45,11 +45,13 @@ jobs: # credentials. We re-authenticate explicitly at push time below. persist-credentials: false + # No dependency cache on the publish path: a poisoned cache could be + # baked into the dist bundles served from the CDN. Fetch fresh from the + # registry with integrity verification (zizmor: cache-poisoning). - name: Setup Node uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: 22 - cache: npm - name: Install dependencies run: npm ci diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5e8f56ae..e0f18cf5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,10 +24,12 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + # No dependency cache on the release path: a poisoned cache could be + # baked into the published release artifacts. Fetch fresh from the + # registry with integrity verification (zizmor: cache-poisoning). - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: 22 - cache: npm - run: npm ci - name: Sync version constants to tag env: From 879e73304ad135c617bbeda02793a49da1b652a3 Mon Sep 17 00:00:00 2001 From: Kiro Agent <244629292+kiro-agent@users.noreply.github.com> Date: Mon, 8 Jun 2026 17:01:56 +0000 Subject: [PATCH 3/3] ci: drop advanced CodeQL workflow (repo uses default setup) SLASHED already runs CodeQL via GitHub's default setup (configured in repo settings, no workflow file). An advanced workflow conflicts with it: the SARIF upload is rejected with "CodeQL analyses from advanced configurations cannot be processed when the default setup is enabled", which was the only failing check on this PR. Remove the redundant workflow and keep relying on default setup for the framework's JS/Actions scanning. --- .github/workflows/codeql.yml | 39 ------------------------------------ 1 file changed, 39 deletions(-) delete mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 630435d3..00000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: CodeQL - -# Static security analysis for the build/test/docs tooling (scripts/, tests/) -# and the workflow definitions themselves. Mirrors the SLASHED-Plugins setup so -# both repositories get the same security coverage. - -on: - push: - branches: [main] - pull_request: - schedule: - - cron: '0 8 * * 1' - -permissions: - contents: read - actions: read - security-events: write - -jobs: - analyze: - name: Analyze (${{ matrix.language }}) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - language: [javascript-typescript, actions] - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - uses: github/codeql-action/init@b0c4fd77f6c559021d78430ec4d0d169ae74a4eb # v3 - with: - languages: ${{ matrix.language }} - queries: security-extended - - - uses: github/codeql-action/analyze@b0c4fd77f6c559021d78430ec4d0d169ae74a4eb # v3 - with: - category: /language:${{ matrix.language }}