name: Rolling Release on: workflow_run: workflows: ["CI"] types: [completed] permissions: checks: read contents: write jobs: verify: name: Verify Edge Release runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion == 'success' }} outputs: should_release: ${{ steps.check.outputs.should_release }} steps: - name: Check `edge` tag matches CI commit id: check uses: actions/github-script@v6 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const tag = await github.rest.git.getRef({ owner: context.repo.owner, repo: context.repo.repo, ref: 'tags/edge' }); const edgeSha = tag.data.object.sha; const ciSha = context.payload.workflow_run.head_sha; if (edgeSha !== ciSha) { console.log(`⚠️ edge tag (${edgeSha}) ≠ CI commit (${ciSha}); skipping release.`); core.setOutput('should_release', 'false'); return; } core.setOutput('should_release', 'true'); console.log('✅ edge tag matches; proceeding with release.'); build: name: Build Binaries and Linux Packages needs: verify if: ${{ needs.verify.outputs.should_release == 'true' }} runs-on: ubuntu-latest steps: - name: Checkout CI-tested commit uses: actions/checkout@v6 with: ref: ${{ github.event.workflow_run.head_sha }} - name: Set up Go uses: actions/setup-go@v6 with: go-version: "1.27.1" - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: "22.14.0" cache: npm cache-dependency-path: ui/package-lock.json - name: Build UI run: make ui - name: Build release binaries with WAL helper run: make -j$(nproc) release wal=1 - name: Build compatibility binaries run: make -j$(nproc) compat - name: Build Linux packages run: make package-linux - name: Upload release binaries uses: actions/upload-artifact@v4 with: name: edge-release-binaries if-no-files-found: error path: | bin/** dist/pkg/linux/**/*.deb dist/pkg/linux/**/*.rpm publish: name: Publish Edge Release needs: [verify, build] if: ${{ needs.verify.outputs.should_release == 'true' }} runs-on: ubuntu-latest steps: - name: Download all artifacts uses: actions/download-artifact@v4 with: path: release - name: Remove stale Linux package assets uses: actions/github-script@v6 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const assetPattern = /\.(deb|rpm)$/; let release; try { const response = await github.rest.repos.getReleaseByTag({ owner: context.repo.owner, repo: context.repo.repo, tag: 'edge', }); release = response.data; } catch (error) { if (error.status === 404) { console.log('No existing edge release found; nothing to prune.'); return; } throw error; } const assets = await github.paginate(github.rest.repos.listReleaseAssets, { owner: context.repo.owner, repo: context.repo.repo, release_id: release.id, per_page: 100, }); const staleAssets = assets.filter((asset) => assetPattern.test(asset.name)); if (staleAssets.length === 0) { console.log('No stale .deb or .rpm assets found.'); return; } for (const asset of staleAssets) { console.log(`Deleting stale asset: ${asset.name}`); await github.rest.repos.deleteReleaseAsset({ owner: context.repo.owner, repo: context.repo.repo, asset_id: asset.id, }); } - name: Publish rolling “edge” release uses: softprops/action-gh-release@v1 with: name: "Automatic Build on main branch" body: | This is a rolling release with the latest build artifacts on main branch. The release is updated every time the `edge` tag is moved. prerelease: true tag_name: edge files: release/**/*