name: Runner CD on: workflow_dispatch: push: paths: - releaseVersion jobs: check: if: startsWith(github.ref, 'refs/heads/releases/') || github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 # Make sure ./releaseVersion match ./src/runnerversion # Query GitHub release ensure version is not used - name: Check version uses: actions/github-script@v7.0.1 with: github-token: ${{secrets.GITHUB_TOKEN}} script: | const fs = require('fs'); const runnerVersion = fs.readFileSync('${{ github.workspace }}/src/runnerversion', 'utf8').replace(/\n$/g, '') const releaseVersion = fs.readFileSync('${{ github.workspace }}/releaseVersion', 'utf8').replace(/\n$/g, '') if (runnerVersion != releaseVersion) { console.log('Request Release Version: ' + releaseVersion + '\nCurrent Runner Version: ' + runnerVersion) core.setFailed('Version mismatch! Make sure ./releaseVersion match ./src/runnerVersion') return } try { const release = await github.rest.repos.getReleaseByTag({ owner: '${{ github.event.repository.owner.name }}', repo: '${{ github.event.repository.name }}', tag: 'v' + runnerVersion }) core.setFailed('Release with same tag already created: ' + release.data.html_url) } catch (e) { // We are good to create the release if release with same tag doesn't exists if (e.status != 404) { throw e } } build: needs: check outputs: linux-x64-sha: ${{ steps.sha.outputs.linux-x64-sha256 }} linux-arm64-sha: ${{ steps.sha.outputs.linux-arm64-sha256 }} linux-arm-sha: ${{ steps.sha.outputs.linux-arm-sha256 }} win-x64-sha: ${{ steps.sha.outputs.win-x64-sha256 }} win-arm64-sha: ${{ steps.sha.outputs.win-arm64-sha256 }} osx-x64-sha: ${{ steps.sha.outputs.osx-x64-sha256 }} osx-arm64-sha: ${{ steps.sha.outputs.osx-arm64-sha256 }} strategy: matrix: runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64, osx-arm64, win-arm64 ] include: - runtime: linux-x64 os: ubuntu-latest devScript: ./dev.sh - runtime: linux-arm64 os: ubuntu-latest devScript: ./dev.sh - runtime: linux-arm os: ubuntu-latest devScript: ./dev.sh - runtime: osx-x64 os: macOS-latest devScript: ./dev.sh - runtime: osx-arm64 os: macOS-latest devScript: ./dev.sh - runtime: win-x64 os: windows-latest devScript: ./dev - runtime: win-arm64 os: windows-latest devScript: ./dev runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v5 # Build runner layout - name: Build & Layout Release run: | ${{ matrix.devScript }} layout Release ${{ matrix.runtime }} working-directory: src # Create runner package tar.gz/zip - name: Package Release if: github.event_name != 'pull_request' run: | ${{ matrix.devScript }} package Release ${{ matrix.runtime }} working-directory: src # compute shas and set as job outputs to use in release notes - run: brew install coreutils #needed for shasum util if: ${{ matrix.os == 'macOS-latest' }} name: Install Dependencies for SHA Calculation (osx) - run: | file=$(ls) sha=$(sha256sum $file | awk '{ print $1 }') echo "Computed sha256: $sha for $file" echo "${{matrix.runtime}}-sha256=$sha" >> $GITHUB_OUTPUT shell: bash id: sha name: Compute SHA256 working-directory: _package # Upload runner package tar.gz/zip as artifact. - name: Publish Artifact if: github.event_name != 'pull_request' uses: actions/upload-artifact@v4 with: name: runner-packages-${{ matrix.runtime }} path: | _package release: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 # Download runner package tar.gz/zip produced by 'build' job - name: Download Artifact (win-x64) uses: actions/download-artifact@v5 with: name: runner-packages-win-x64 path: ./ - name: Download Artifact (win-arm64) uses: actions/download-artifact@v5 with: name: runner-packages-win-arm64 path: ./ - name: Download Artifact (osx-x64) uses: actions/download-artifact@v5 with: name: runner-packages-osx-x64 path: ./ - name: Download Artifact (osx-arm64) uses: actions/download-artifact@v5 with: name: runner-packages-osx-arm64 path: ./ - name: Download Artifact (linux-x64) uses: actions/download-artifact@v5 with: name: runner-packages-linux-x64 path: ./ - name: Download Artifact (linux-arm) uses: actions/download-artifact@v5 with: name: runner-packages-linux-arm path: ./ - name: Download Artifact (linux-arm64) uses: actions/download-artifact@v5 with: name: runner-packages-linux-arm64 path: ./ # Create ReleaseNote file - name: Create ReleaseNote id: releaseNote uses: actions/github-script@v7.0.1 with: github-token: ${{secrets.GITHUB_TOKEN}} script: | const fs = require('fs'); const runnerVersion = fs.readFileSync('${{ github.workspace }}/src/runnerversion', 'utf8').replace(/\n$/g, '') var releaseNote = fs.readFileSync('${{ github.workspace }}/releaseNote.md', 'utf8').replace(//g, runnerVersion) releaseNote = releaseNote.replace(//g, '${{needs.build.outputs.win-x64-sha}}') releaseNote = releaseNote.replace(//g, '${{needs.build.outputs.win-arm64-sha}}') releaseNote = releaseNote.replace(//g, '${{needs.build.outputs.osx-x64-sha}}') releaseNote = releaseNote.replace(//g, '${{needs.build.outputs.osx-arm64-sha}}') releaseNote = releaseNote.replace(//g, '${{needs.build.outputs.linux-x64-sha}}') releaseNote = releaseNote.replace(//g, '${{needs.build.outputs.linux-arm-sha}}') releaseNote = releaseNote.replace(//g, '${{needs.build.outputs.linux-arm64-sha}}') console.log(releaseNote) core.setOutput('version', runnerVersion); core.setOutput('note', releaseNote); - name: Validate Packages HASH run: | ls -l echo "${{needs.build.outputs.win-x64-sha}} actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip" | shasum -a 256 -c echo "${{needs.build.outputs.win-arm64-sha}} actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}.zip" | shasum -a 256 -c echo "${{needs.build.outputs.osx-x64-sha}} actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c echo "${{needs.build.outputs.osx-arm64-sha}} actions-runner-osx-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c echo "${{needs.build.outputs.linux-x64-sha}} actions-runner-linux-x64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c echo "${{needs.build.outputs.linux-arm-sha}} actions-runner-linux-arm-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c echo "${{needs.build.outputs.linux-arm64-sha}} actions-runner-linux-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c # Create GitHub release - uses: actions/create-release@master id: createRelease name: Create ${{ steps.releaseNote.outputs.version }} Runner Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: "v${{ steps.releaseNote.outputs.version }}" release_name: "v${{ steps.releaseNote.outputs.version }}" body: | ${{ steps.releaseNote.outputs.note }} # Upload release assets (full runner packages) - name: Upload Release Asset (win-x64) uses: actions/upload-release-asset@v1.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.createRelease.outputs.upload_url }} asset_path: ${{ github.workspace }}/actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip asset_content_type: application/octet-stream - name: Upload Release Asset (win-arm64) uses: actions/upload-release-asset@v1.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.createRelease.outputs.upload_url }} asset_path: ${{ github.workspace }}/actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}.zip asset_name: actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}.zip asset_content_type: application/octet-stream - name: Upload Release Asset (linux-x64) uses: actions/upload-release-asset@v1.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.createRelease.outputs.upload_url }} asset_path: ${{ github.workspace }}/actions-runner-linux-x64-${{ steps.releaseNote.outputs.version }}.tar.gz asset_name: actions-runner-linux-x64-${{ steps.releaseNote.outputs.version }}.tar.gz asset_content_type: application/octet-stream - name: Upload Release Asset (osx-x64) uses: actions/upload-release-asset@v1.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.createRelease.outputs.upload_url }} asset_path: ${{ github.workspace }}/actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}.tar.gz asset_name: actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}.tar.gz asset_content_type: application/octet-stream - name: Upload Release Asset (osx-arm64) uses: actions/upload-release-asset@v1.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.createRelease.outputs.upload_url }} asset_path: ${{ github.workspace }}/actions-runner-osx-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz asset_name: actions-runner-osx-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz asset_content_type: application/octet-stream - name: Upload Release Asset (linux-arm) uses: actions/upload-release-asset@v1.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.createRelease.outputs.upload_url }} asset_path: ${{ github.workspace }}/actions-runner-linux-arm-${{ steps.releaseNote.outputs.version }}.tar.gz asset_name: actions-runner-linux-arm-${{ steps.releaseNote.outputs.version }}.tar.gz asset_content_type: application/octet-stream - name: Upload Release Asset (linux-arm64) uses: actions/upload-release-asset@v1.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.createRelease.outputs.upload_url }} asset_path: ${{ github.workspace }}/actions-runner-linux-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz asset_name: actions-runner-linux-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz asset_content_type: application/octet-stream publish-image: needs: release runs-on: ubuntu-latest permissions: contents: read packages: write id-token: write attestations: write env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository_owner }}/actions-runner steps: - name: Checkout repository uses: actions/checkout@v5 - name: Compute image version id: image uses: actions/github-script@v7.0.1 with: script: | const fs = require('fs'); const runnerVersion = fs.readFileSync('${{ github.workspace }}/releaseVersion', 'utf8').replace(/\n$/g, '') console.log(`Using runner version ${runnerVersion}`) core.setOutput('version', runnerVersion); - name: Setup Docker buildx uses: docker/setup-buildx-action@v3 - name: Log into registry ${{ env.REGISTRY }} uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push Docker image id: build-and-push uses: docker/build-push-action@v6 with: context: ./images platforms: | linux/amd64 linux/arm64 tags: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.image.outputs.version }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest build-args: | RUNNER_VERSION=${{ steps.image.outputs.version }} push: true labels: | org.opencontainers.image.source=${{github.server_url}}/${{github.repository}} org.opencontainers.image.description=https://github.com/actions/runner/releases/tag/v${{ steps.image.outputs.version }} org.opencontainers.image.licenses=MIT - name: Generate attestation uses: actions/attest-build-provenance@v2 with: subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} subject-digest: ${{ steps.build-and-push.outputs.digest }} push-to-registry: true