From 5e4416c9cb2c5b458bad7f5add4991b38d75a7ee Mon Sep 17 00:00:00 2001 From: maj00r Date: Tue, 25 Aug 2026 23:32:36 +0200 Subject: [PATCH] Publish rolling pre-releases for main and staging Workflow artifacts can only be downloaded by signed-in users with access to the repository, so they are useless for handing a build to anyone else. After the matrix publishes, a release job recreates a rolling pre-release from the same packages; its assets are downloadable without an account: releases/download/latest/ from main releases/download/staging/ from staging Each branch owns its tag, so a staging build never overwrites the main one. The release is deleted and created again rather than edited, so the tag follows its branch and assets from an older build do not linger. Write access is granted to that job only, the workflow default stays read. --- .github/workflows/dotnet.yml | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 7e70c7c..b262753 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -4,10 +4,12 @@ on: push: branches: - main + - staging pull_request: branches: - main + - staging workflow_dispatch: @@ -105,3 +107,46 @@ jobs: path: ${{ matrix.package }} if-no-files-found: error archive: false + + # Workflow artifacts are only reachable for signed-in users with repository + # access, so every build of a release branch also lands in a rolling + # pre-release, whose assets anyone can download: + # https://github.com/${{ github.repository }}/releases/download// + # main -> "latest", staging -> "staging"; the two never overwrite each other. + release: + name: Rolling pre-release + needs: publish + if: github.event_name == 'push' + runs-on: ubuntu-latest + + permissions: + contents: write + + env: + RELEASE_TAG: ${{ github.ref_name == 'main' && 'latest' || 'staging' }} + RELEASE_NAME: ${{ github.ref_name == 'main' && 'Latest build' || 'Staging build' }} + + steps: + - name: Collect the packages + uses: actions/download-artifact@v7 + with: + path: dist + merge-multiple: true + + # Recreated rather than edited, so the tag follows its branch and no asset + # from an older build is left behind. + - name: Replace the rolling pre-release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + + ls -l dist + + gh release delete "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --yes --cleanup-tag || true + gh release create "$RELEASE_TAG" dist/* \ + --repo "$GITHUB_REPOSITORY" \ + --target "$GITHUB_SHA" \ + --prerelease \ + --title "$RELEASE_NAME" \ + --notes "Automatic build of $GITHUB_REF_NAME (${GITHUB_SHA::7}), $(date -u '+%Y-%m-%d %H:%M UTC')."