diff --git a/.gitea/workflows/cms-content-validation.yml b/.gitea/workflows/cms-content-validation.yml index d05f34f..0c785f3 100644 --- a/.gitea/workflows/cms-content-validation.yml +++ b/.gitea/workflows/cms-content-validation.yml @@ -15,9 +15,9 @@ jobs: ASTRO_TELEMETRY_DISABLED: '1' steps: - name: Checkout source - uses: https://github.com/actions/checkout@v4 + uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Use Node 22 - uses: https://github.com/actions/setup-node@v4 + uses: https://github.com/actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 22 cache: npm diff --git a/.gitea/workflows/deploy-blog.yml b/.gitea/workflows/deploy-blog.yml index 51c11de..4cd75a0 100644 --- a/.gitea/workflows/deploy-blog.yml +++ b/.gitea/workflows/deploy-blog.yml @@ -28,9 +28,9 @@ jobs: ASTRO_TELEMETRY_DISABLED: '1' steps: - name: Checkout source - uses: https://github.com/actions/checkout@v4 + uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Use Node 22 - uses: https://github.com/actions/setup-node@v4 + uses: https://github.com/actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 22 cache: npm diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 91cc1b9..cbbaa0b 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -28,9 +28,9 @@ jobs: ASTRO_TELEMETRY_DISABLED: '1' steps: - name: Checkout source - uses: https://github.com/actions/checkout@v4 + uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Use Node 22 - uses: https://github.com/actions/setup-node@v4 + uses: https://github.com/actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 22 cache: npm diff --git a/.gitea/workflows/production-blog.yml b/.gitea/workflows/production-blog.yml index d015bf0..20ff24e 100644 --- a/.gitea/workflows/production-blog.yml +++ b/.gitea/workflows/production-blog.yml @@ -29,9 +29,9 @@ jobs: ASTRO_TELEMETRY_DISABLED: '1' steps: - name: Checkout source - uses: https://github.com/actions/checkout@v4 + uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Use Node 22 - uses: https://github.com/actions/setup-node@v4 + uses: https://github.com/actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 22 cache: npm diff --git a/.gitea/workflows/production-candidate.yml b/.gitea/workflows/production-candidate.yml index 2a773d8..7778ee9 100644 --- a/.gitea/workflows/production-candidate.yml +++ b/.gitea/workflows/production-candidate.yml @@ -29,9 +29,9 @@ jobs: ASTRO_TELEMETRY_DISABLED: '1' steps: - name: Checkout source - uses: https://github.com/actions/checkout@v4 + uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Use Node 22 - uses: https://github.com/actions/setup-node@v4 + uses: https://github.com/actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 22 cache: npm diff --git a/docs/decap-cms-gitea-setup.md b/docs/decap-cms-gitea-setup.md index 398d84b..1726bf2 100644 --- a/docs/decap-cms-gitea-setup.md +++ b/docs/decap-cms-gitea-setup.md @@ -29,6 +29,27 @@ If Cloudflare later assigns a different stable origin, update the repository configuration, CORS origin, and OAuth redirect URI together through review before enabling login. +## Runner cache settings + +The Dockerized runner uses a persistent `/data` volume and the same dedicated +Docker network as its job containers. Its non-confidential cache settings are: + +```yaml +cache: + enabled: true + dir: /data/cache + host: sloanops-gitea-runner + port: 8088 + offline_mode: true +container: + network: sloanops-actions +``` + +`offline_mode` is safe here because every external `uses:` reference is pinned +to a reviewed full commit SHA. It prevents the runner from refreshing mutable +action branches on every job; npm packages remain keyed separately by +`package-lock.json` through setup-node's cache integration. + ## Applied CORS policy The tracked Gitea service in diff --git a/docs/decap-cms-pilot.md b/docs/decap-cms-pilot.md index d84f2ba..d726b9f 100644 --- a/docs/decap-cms-pilot.md +++ b/docs/decap-cms-pilot.md @@ -88,6 +88,10 @@ staging branch: fixed host and port reachable from job containers, avoiding the timeout caused by its former auto-detected private address. Warm jobs reuse dependency tarballs without caching `node_modules`. +- All external workflow actions are pinned to reviewed commit SHAs. The runner + may therefore set `cache.offline_mode: true` and reuse its local action + repository cache without trusting a mutable tag or refreshing GitHub on every + job. The pilot dependencies were verified on `cms-pilot`. The same protection rules apply to `cms`; its exact-origin CORS and OAuth values are the remaining diff --git a/scripts/verify-decap.mjs b/scripts/verify-decap.mjs index c8f6139..b7681b2 100644 --- a/scripts/verify-decap.mjs +++ b/scripts/verify-decap.mjs @@ -227,6 +227,8 @@ for (const path of [ '.gitea/workflows/production-blog.yml', ]) { const text = await readFile(path, 'utf8'); + assert(text.includes('uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4'), `${path} must pin checkout v4 to its reviewed commit.`); + assert(text.includes('uses: https://github.com/actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4'), `${path} must pin setup-node v4 to its reviewed commit.`); assert(/cache:\s*npm/.test(text) && /cache-dependency-path:\s*package-lock\.json/.test(text), `${path} must cache npm downloads by package-lock.json.`); assert(text.includes('npm ci --prefer-offline --no-audit --no-fund'), `${path} must retain a clean lockfile install with quiet, cache-friendly npm options.`); }