diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4253dfe..cb221e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -173,11 +173,7 @@ jobs: lume_macos_contract_trusted: name: lume macos contract if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository - runs-on: - - self-hosted - - macOS - - ARM64 - - xcode + runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/release-image.yml b/.github/workflows/release-image.yml index 71c796e..16bb82c 100644 --- a/.github/workflows/release-image.yml +++ b/.github/workflows/release-image.yml @@ -28,11 +28,7 @@ env: jobs: publish_and_verify: name: publish-and-verify - runs-on: - - self-hosted - - linux - - shell-only - - public + runs-on: ubuntu-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} SYNOLOGY_RUNNER_BASE_DIR: /volume1/docker/github-runner-fleet @@ -109,6 +105,10 @@ jobs: process.env.GITHUB_OUTPUT, `image_ref=${config.image.repository}:${config.image.tag}\n` ); + fs.appendFileSync( + process.env.GITHUB_OUTPUT, + `image_repo=${config.image.repository}\n` + ); fs.appendFileSync( process.env.GITHUB_OUTPUT, `image_tag=${config.image.tag}\n` @@ -177,7 +177,7 @@ jobs: - name: Emit SLSA provenance uses: actions/attest-build-provenance@v3 with: - subject-name: ${{ steps.release_meta.outputs.image_ref }} + subject-name: ${{ steps.release_meta.outputs.image_repo }} subject-digest: ${{ steps.image_digest.outputs.digest }} push-to-registry: true diff --git a/.github/workflows/rg-security.yml b/.github/workflows/rg-security.yml index b627857..9a92095 100644 --- a/.github/workflows/rg-security.yml +++ b/.github/workflows/rg-security.yml @@ -20,11 +20,7 @@ permissions: jobs: security: name: rg-security - runs-on: - - self-hosted - - linux - - shell-only - - public + runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 6d9f509..0fcb4ff 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -14,11 +14,7 @@ permissions: jobs: scorecard: name: openssf-scorecard - runs-on: - - self-hosted - - linux - - shell-only - - public + runs-on: ubuntu-latest permissions: contents: read id-token: write diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index c0f1e66..af7a475 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -21,11 +21,7 @@ env: jobs: codeql: name: codeql - runs-on: - - self-hosted - - linux - - shell-only - - public + runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v6 @@ -37,11 +33,7 @@ jobs: dependency_review: name: dependency-review if: github.event_name == 'pull_request' - runs-on: - - self-hosted - - linux - - shell-only - - public + runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@v6 @@ -52,11 +44,7 @@ jobs: osv: name: osv - runs-on: - - self-hosted - - linux - - shell-only - - public + runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@v6 diff --git a/scripts/lume/install-runtime.sh b/scripts/lume/install-runtime.sh index c9c1482..a44594b 100755 --- a/scripts/lume/install-runtime.sh +++ b/scripts/lume/install-runtime.sh @@ -67,7 +67,7 @@ GITHUB_API_URL=https://api.github.com LUME_RUNNER_BASE_DIR='${lume_base_dir}' LUME_RUNNER_ENV_FILE='${lume_base_dir}/runner.env' COMPOSE_PROJECT_NAME=github-runner-fleet -RUNNER_VERSION=2.333.0 +RUNNER_VERSION=2.334.0 EOF install -m 0600 "${temp_path}" "${env_path}" rm -f "${temp_path}" diff --git a/test/lume-scripts.test.ts b/test/lume-scripts.test.ts index 62f0640..1fe96f0 100644 --- a/test/lume-scripts.test.ts +++ b/test/lume-scripts.test.ts @@ -46,6 +46,8 @@ describe("Lume pool scripts", () => { expect(installRuntime).toContain("Library/Application Support/github-runner-fleet/controller"); expect(installRuntime).toContain("rsync -a --delete"); expect(installRuntime).toContain("pnpm --dir"); + expect(installRuntime).toContain("RUNNER_VERSION=2.334.0"); + expect(installRuntime).not.toContain("RUNNER_VERSION=2.333.0"); expect(installRuntime).toContain("install_lume_controller_runtime"); expect(installRuntime).toContain('if [[ -f "${runtime_env}" ]]'); expect(installRuntime.indexOf('if [[ -f "${runtime_env}" ]]')).toBeLessThan( diff --git a/test/release-workflow.test.ts b/test/release-workflow.test.ts index 0c8ed49..76244dc 100644 --- a/test/release-workflow.test.ts +++ b/test/release-workflow.test.ts @@ -3,10 +3,8 @@ import path from "node:path"; import YAML from "yaml"; import { describe, expect, test } from "vitest"; -const shellSafePublicRunner = ["self-hosted", "linux", "shell-only", "public"]; - describe("release workflow", () => { - test("publishes on shell-safe self-hosted runners, verifies the pushed tag, and can create a repo release from main", () => { + test("publishes on GitHub-hosted runners, verifies the pushed tag, and can create a repo release from main", () => { const workflow = YAML.parse( fs.readFileSync( path.resolve(".github/workflows/release-image.yml"), @@ -41,7 +39,7 @@ describe("release workflow", () => { "id-token": "write", attestations: "write" }); - expect(job["runs-on"]).toEqual(shellSafePublicRunner); + expect(job["runs-on"]).toBe("ubuntu-latest"); expect(job.env).toMatchObject({ GITHUB_PAT: "${{ secrets.GITHUB_TOKEN }}", SYNOLOGY_RUNNER_BASE_DIR: "/volume1/docker/github-runner-fleet" @@ -65,6 +63,25 @@ describe("release workflow", () => { expect( steps.some((step) => step.uses === "actions/attest-build-provenance@v3") ).toBe(true); + expect( + steps.some( + (step) => + typeof step.run === "string" && + step.run.includes("image_ref=${config.image.repository}:${config.image.tag}") && + step.run.includes("image_repo=${config.image.repository}") + ) + ).toBe(true); + expect( + steps.some( + (step) => + step.name === "Emit SLSA provenance" && + step.with && + (step.with as Record)["subject-name"] === + "${{ steps.release_meta.outputs.image_repo }}" && + (step.with as Record)["subject-digest"] === + "${{ steps.image_digest.outputs.digest }}" + ) + ).toBe(true); expect( steps.some( (step) => diff --git a/test/security-workflow.test.ts b/test/security-workflow.test.ts index de1c6cf..6edbe3d 100644 --- a/test/security-workflow.test.ts +++ b/test/security-workflow.test.ts @@ -6,7 +6,7 @@ import { describe, expect, test } from "vitest"; const shellSafePublicRunner = ["self-hosted", "linux", "shell-only", "public"]; describe("security and reusable workflows", () => { - test("keeps security scans on shell-safe self-hosted runners with Security tab upload", () => { + test("keeps security scans on GitHub-hosted runners with Security tab upload", () => { const workflow = YAML.parse( fs.readFileSync(path.resolve(".github/workflows/security.yml"), "utf8") ) as { permissions: Record; jobs: Record> }; @@ -16,7 +16,7 @@ describe("security and reusable workflows", () => { "security-events": "write" }); for (const job of Object.values(workflow.jobs)) { - expect(job["runs-on"]).toEqual(shellSafePublicRunner); + expect(job["runs-on"]).toBe("ubuntu-latest"); } expect(String(JSON.stringify(workflow))).toContain("github/codeql-action/init"); expect(String(JSON.stringify(workflow))).toContain("dependency-review-action"); @@ -43,7 +43,7 @@ describe("security and reusable workflows", () => { "id-token": "write", "security-events": "write" }); - expect(workflow.jobs.scorecard["runs-on"]).toEqual(shellSafePublicRunner); + expect(workflow.jobs.scorecard["runs-on"]).toBe("ubuntu-latest"); expect(String(JSON.stringify(workflow))).toContain( "ossf/scorecard-action@v2.4.3" ); @@ -51,7 +51,7 @@ describe("security and reusable workflows", () => { }); test("exposes rg-ci, rg-security, and rg-release as workflow_call artifacts", () => { - for (const fileName of ["rg-ci.yml", "rg-security.yml", "rg-release.yml"]) { + for (const fileName of ["rg-ci.yml", "rg-release.yml"]) { const workflow = YAML.parse( fs.readFileSync(path.resolve(".github/workflows", fileName), "utf8") ) as { on: Record; jobs: Record> }; @@ -61,5 +61,14 @@ describe("security and reusable workflows", () => { expect(job["runs-on"]).toEqual(shellSafePublicRunner); } } + + const rgSecurity = YAML.parse( + fs.readFileSync(path.resolve(".github/workflows/rg-security.yml"), "utf8") + ) as { on: Record; jobs: Record> }; + + expect(rgSecurity.on).toHaveProperty("workflow_call"); + for (const job of Object.values(rgSecurity.jobs)) { + expect(job["runs-on"]).toBe("ubuntu-latest"); + } }); }); diff --git a/test/workflow.test.ts b/test/workflow.test.ts index d4fa439..10411d7 100644 --- a/test/workflow.test.ts +++ b/test/workflow.test.ts @@ -4,7 +4,6 @@ import YAML from "yaml"; import { describe, expect, test } from "vitest"; const shellSafePublicRunner = ["self-hosted", "linux", "shell-only", "public"]; -const macosXcodeRunner = ["self-hosted", "macOS", "ARM64", "xcode"]; describe("CI workflow", () => { test("runs mutation testing in extended validation and uploads the report", () => { @@ -291,7 +290,7 @@ describe("CI workflow", () => { expect(String(syntaxStep?.run)).toContain("docker/runner-entrypoint.ps1"); }); - test("keeps the Lume macOS pool contract on self-hosted macOS runners", () => { + test("keeps the Lume macOS pool contract on GitHub-hosted runners", () => { const workflow = YAML.parse( fs.readFileSync(path.resolve(".github/workflows/ci.yml"), "utf8") ) as { @@ -310,7 +309,7 @@ describe("CI workflow", () => { (step) => step.name === "Validate Lume shell scripts" ); - expect(lumeJob["runs-on"]).toEqual(macosXcodeRunner); + expect(lumeJob["runs-on"]).toBe("ubuntu-latest"); expect(String(renderStep?.run)).toContain("pnpm validate-lume-config"); expect(String(renderStep?.run)).toContain("pnpm render-lume-runner-manifest"); expect(String(lifecycleStep?.run)).toContain("pnpm install-lume-project");