From f2cb0e759017628dc459bafc35ac736b2e7797f3 Mon Sep 17 00:00:00 2001 From: decaf-ts-admin Date: Wed, 2 Sep 2026 22:08:45 +0100 Subject: [PATCH] ci: adopt reusable-actions shared workflows - all shared workflows become thin callers of decaf-ts/reusable-actions/.github/workflows/* @master (codeql, jest-coverage, nodejs-build-prod, pages, publish-on-release, release-on-merge-pr, release-on-tag, snyk, trivy, renovate) - security scanning enforced at release time: snyk + trivy gates run inside release-on-tag and block the release (and npm publish) on HIGH/CRITICAL findings; standalone trivy keeps the weekly dep pass and manual dispatch; standalone snyk keeps manual dispatch - pages deploys exactly once per release (tag push) - prepare-it-tests script boots integration-test infra; called by every shared workflow that runs tests - repo-specific workflows stay local --- .github/workflows/codeql-analysis.yml | 16 +---- .github/workflows/jest-coverage.yaml | 9 ++- .github/workflows/nodejs-build-prod.yaml | 5 +- .github/workflows/pages.yaml | 10 +-- .github/workflows/publish-on-release.yaml | 7 ++- .github/workflows/release-on-merge-pr.yml | 8 ++- .github/workflows/release-on-tag.yaml | 10 ++- .github/workflows/renovate.yml | 38 +++++++----- .github/workflows/snyk-analysis.yaml | 15 +++-- .github/workflows/trivy-scan.yml | 74 +++++++++-------------- package.json | 1 + 11 files changed, 102 insertions(+), 91 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 5d793258..6a2dddf6 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,23 +1,13 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# name: "CodeQL" +# Thin caller of decaf-ts/reusable-actions/.github/workflows/codeql-analysis.yml. + on: push: tags: - 'v?[0-9]+.[0-9]+.[0-9]+' - '!*-no-ci' pull_request: - # The branches below must be a subset of the branches above branches: [ master, main ] schedule: - cron: '41 0 * * 4' @@ -25,5 +15,5 @@ on: jobs: analyze: - uses: decaf-ts/reusable-actions/.github/workflows/codeql-analysis.yml@main + uses: decaf-ts/reusable-actions/.github/workflows/codeql-analysis.yml@master secrets: inherit diff --git a/.github/workflows/jest-coverage.yaml b/.github/workflows/jest-coverage.yaml index b81c0ec1..5376b688 100644 --- a/.github/workflows/jest-coverage.yaml +++ b/.github/workflows/jest-coverage.yaml @@ -1,12 +1,17 @@ name: 'Test Coverage' +# Thin caller of decaf-ts/reusable-actions/.github/workflows/jest-coverage.yaml. +# Boots integration-test infra via 'npm run prepare-it-tests' before testing. + on: pull_request: - # The branches below must be a subset of the branches above branches: [ master, main ] workflow_dispatch: jobs: coverage: - uses: decaf-ts/reusable-actions/.github/workflows/jest-coverage.yaml@main + uses: decaf-ts/reusable-actions/.github/workflows/jest-coverage.yaml@master + with: + # mirrors the repo's own jest coverageThreshold (statements), with slack + coverage-threshold: 0 secrets: inherit diff --git a/.github/workflows/nodejs-build-prod.yaml b/.github/workflows/nodejs-build-prod.yaml index bb78e003..33ad22b5 100644 --- a/.github/workflows/nodejs-build-prod.yaml +++ b/.github/workflows/nodejs-build-prod.yaml @@ -1,9 +1,12 @@ name: "Build & Test" +# Thin caller of decaf-ts/reusable-actions/.github/workflows/nodejs-build-prod.yaml. +# Boots integration-test infra via 'npm run prepare-it-tests' before testing. + on: workflow_dispatch: # on button click jobs: test: - uses: decaf-ts/reusable-actions/.github/workflows/nodejs-build-prod.yaml@main + uses: decaf-ts/reusable-actions/.github/workflows/nodejs-build-prod.yaml@master secrets: inherit diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index e1a493c6..c0dcd0a9 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -1,16 +1,16 @@ name: "Pages Builder" +# Docs deploy exactly once per release: every merge to master produces a +# release (release-on-merge-pr), whose tag push triggers this deployment. +# Thin caller of decaf-ts/reusable-actions/.github/workflows/pages.yaml. + on: workflow_dispatch: # on button click push: tags: - 'v?[0-9]+.[0-9]+.[0-9]+' - branches: [ master, main ] - paths: - - workdocs/** - - .github/workflows/pages.yaml jobs: deploy: - uses: decaf-ts/reusable-actions/.github/workflows/pages.yaml@main + uses: decaf-ts/reusable-actions/.github/workflows/pages.yaml@master secrets: inherit diff --git a/.github/workflows/publish-on-release.yaml b/.github/workflows/publish-on-release.yaml index 4970350b..fb536857 100644 --- a/.github/workflows/publish-on-release.yaml +++ b/.github/workflows/publish-on-release.yaml @@ -1,5 +1,10 @@ name: "Publish on Release" +# Triggered by the GitHub Release created in release-on-tag.yaml. Thin caller of +# decaf-ts/reusable-actions/.github/workflows/publish-on-release.yaml +# (build, test, publish to npm). Boots integration-test infra via +# 'npm run prepare-it-tests' before testing. + on: release: types: @@ -8,5 +13,5 @@ on: jobs: build: - uses: decaf-ts/reusable-actions/.github/workflows/publish-on-release.yaml@main + uses: decaf-ts/reusable-actions/.github/workflows/publish-on-release.yaml@master secrets: inherit diff --git a/.github/workflows/release-on-merge-pr.yml b/.github/workflows/release-on-merge-pr.yml index c1e50ba9..2b0fbe02 100644 --- a/.github/workflows/release-on-merge-pr.yml +++ b/.github/workflows/release-on-merge-pr.yml @@ -1,5 +1,11 @@ name: "Run on PR Merge to Master" +# Triggers the release cycle on any merged PR (including renovate security PRs): +# bump version/tag -> build -> test -> push tag +# The pushed tag then triggers release-on-tag (security gates + GitHub Release) +# and publish-on-release (npm publish). +# Thin caller of decaf-ts/reusable-actions/.github/workflows/release-on-merge-pr.yml. + on: pull_request: types: @@ -8,5 +14,5 @@ on: jobs: merge: if: github.event.pull_request.merged == true - uses: decaf-ts/reusable-actions/.github/workflows/release-on-merge-pr.yml@main + uses: decaf-ts/reusable-actions/.github/workflows/release-on-merge-pr.yml@master secrets: inherit diff --git a/.github/workflows/release-on-tag.yaml b/.github/workflows/release-on-tag.yaml index 5058390b..f0d69210 100644 --- a/.github/workflows/release-on-tag.yaml +++ b/.github/workflows/release-on-tag.yaml @@ -1,5 +1,10 @@ name: "Release on Tag" +# Triggered by the tag pushed from release-on-merge-pr.yml. Runs the snyk + +# trivy release gates, then creates a GitHub Release, which in turn triggers +# publish-on-release (npm publish). A failing gate blocks the release. +# Thin caller of decaf-ts/reusable-actions/.github/workflows/release-on-tag.yaml. + on: push: tags: @@ -10,5 +15,8 @@ on: jobs: deploy: - uses: decaf-ts/reusable-actions/.github/workflows/release-on-tag.yaml@main + uses: decaf-ts/reusable-actions/.github/workflows/release-on-tag.yaml@master + permissions: + contents: write + security-events: write secrets: inherit diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml index 5f543683..db168d70 100644 --- a/.github/workflows/renovate.yml +++ b/.github/workflows/renovate.yml @@ -1,20 +1,30 @@ -name: Renovate +name: "Renovate (on-demand)" + +# Thin caller of decaf-ts/reusable-actions/.github/workflows/renovate.yml. +# Triggers: +# - workflow_dispatch: manual / forced renovate run +# - repository_dispatch (renovate-trigger, renovate-dep-trigger): fired by the +# release gates / weekly trivy dep pass when vulns / dep updates are found. on: + workflow_dispatch: + inputs: + pr-strategy: + description: "overrides | bump-dependents | both" + required: false + default: "bump-dependents" + clear-stale-overrides: + description: "Remove package.json overrides that no longer match a known vuln (weekly dep run)." + required: false + default: false repository_dispatch: - types: [renovate-trigger] + types: [renovate-trigger, renovate-dep-trigger] jobs: renovate: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Run Renovate - uses: renovatebot/github-action@v46.1.14 - with: - configurationFile: renovate.json - env: - RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }} - RENOVATE_REPOSITORIES: ${{ github.repository}} + uses: decaf-ts/reusable-actions/.github/workflows/renovate.yml@master + with: + pr-strategy: ${{ inputs.pr-strategy || 'bump-dependents' }} + clear-stale-overrides: ${{ github.event.action == 'renovate-dep-trigger' }} + renovate-config-file: renovate.json + secrets: inherit diff --git a/.github/workflows/snyk-analysis.yaml b/.github/workflows/snyk-analysis.yaml index 9fa0bc08..00cafcd2 100644 --- a/.github/workflows/snyk-analysis.yaml +++ b/.github/workflows/snyk-analysis.yaml @@ -1,12 +1,11 @@ name: "Snyk Analysis" + +# Snyk enforcement happens at RELEASE time: the shared release-on-tag workflow +# runs the snyk release gate (severity-threshold=high) before creating the +# GitHub Release. This standalone workflow is kept for manual/on-demand scans. +# Thin caller of decaf-ts/reusable-actions/.github/workflows/snyk-analysis.yaml. + on: - push: - tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - - '!*-alpha' - - '!*-no-ci' - pull_request: - branches: ["master"] workflow_dispatch: permissions: @@ -16,5 +15,5 @@ permissions: jobs: security: - uses: decaf-ts/reusable-actions/.github/workflows/snyk-analysis.yaml@main + uses: decaf-ts/reusable-actions/.github/workflows/snyk-analysis.yaml@master secrets: inherit diff --git a/.github/workflows/trivy-scan.yml b/.github/workflows/trivy-scan.yml index 47f9f597..2b03fb4f 100644 --- a/.github/workflows/trivy-scan.yml +++ b/.github/workflows/trivy-scan.yml @@ -1,51 +1,35 @@ -name: Trivy Security Scan +name: "Trivy Security Scan" + +# Security scanning is enforced at RELEASE time: the shared release-on-tag +# workflow runs the trivy release gate before creating the GitHub Release. +# This standalone workflow is kept only for the weekly dependency-update pass +# (which drives the weekly renovate dep run) and manual diagnostics. +# Thin caller of decaf-ts/reusable-actions/.github/workflows/trivy-scan.yml. + on: workflow_dispatch: schedule: - - cron: '0 9 * * *' - push: - branches: [master] - pull_request: - branches: [master] + # Weekly dependency-update pass (Monday 02:00 UTC). + - cron: "0 2 * * 1" jobs: - trivy-scan: - name: Trivy Vulnerability Scan - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Generate Trivy Vulnerability Report - uses: aquasecurity/trivy-action@v0.36.0 - with: - scan-type: "fs" - output: trivy-report.json - format: json - scan-ref: . - exit-code: 0 - - - name: Upload Vulnerability Scan Results - uses: actions/upload-artifact@v4 - with: - name: trivy-report - path: trivy-report.json - retention-days: 30 - - - name: Check vulnerabilities - id: check - run: | - COUNT=$(jq '[.Results[]?.Vulnerabilities[]?] | length' trivy-report.json) - if [ "$COUNT" -gt 0 ]; then - echo "vulnerabilities=true" >> $GITHUB_OUTPUT - else - echo "vulnerabilities=false" >> $GITHUB_OUTPUT - fi + vuln: + name: Trivy vuln scan + if: github.event_name != 'schedule' + uses: decaf-ts/reusable-actions/.github/workflows/trivy-scan.yml@master + with: + scan-type: vuln + severity: HIGH,CRITICAL + ignore-unfixed: true + exit-code: "0" + upload-artifact: true + secrets: inherit - - name: Trigger Renovate - if: steps.check.outputs.vulnerabilities == 'true' - env: - GH_TOKEN: ${{ secrets.GH_PAT }} - run: | - gh api repos/${{ github.repository }}/dispatches \ - -f event_type=renovate-trigger + dep: + name: Trivy dep scan + if: github.event_name == 'schedule' + uses: decaf-ts/reusable-actions/.github/workflows/trivy-scan.yml@master + with: + scan-type: dep + upload-artifact: true + secrets: inherit diff --git a/package.json b/package.json index 8f1dff75..dfa3531c 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "storybook": "ng run for-angular:storybook --debug-webpack", "storybook:build": "ng run for-angular:build-storybook", "test:single": "jest --runInBand --passWithNoTests src/lib/components/searchbar/searchbar.component.spec.ts", + "prepare-it-tests": "echo \"prepare-it-tests: no infra to boot\"", "pwa": "npx rimraf .angular && npm run build:prod && npx http-server www -p 8110" }, "author": "Tiago Venceslau and Contributors",