From f10feef23ac40eb9d04f785498bccaadfc248bf2 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sun, 10 Dec 2023 20:04:45 -0800 Subject: [PATCH] create script to determine build number What a pain. It turns out that github.run_number is counting the number of times a specific workflow has been run - but that's different for different workflows, so using that won't get us a single tag with all the corresponding build artifacts. And sadly I can't find a simple atomic way to increase a GitHUb repo variable, so I came up with this somewhat convoluted dance, using the the fact that a push to an existing brach that isn't a fast-forward will fail. Signed-off-by: Dirk Hohndel --- .github/workflows/android.yml | 18 +++++++++- .github/workflows/mac.yml | 17 ++++++++- .github/workflows/windows.yml | 18 +++++++++- scripts/get-or-create-build-nr.sh | 60 +++++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 scripts/get-or-create-build-nr.sh diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 5613dcdc9..480f916db 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -17,6 +17,22 @@ jobs: - name: checkout sources uses: actions/checkout@v1 + - name: atomically create or retrieve the build number + id: build_nr + run: | + cd .. # check out parallel to subsurface sources + url="https://subsurface:${{ secrets.NIGHTLY_BUILDS }}@github.com/subsurface/nightly-builds" + # the clone followed by the pointless push should verify that the password is stored in the config + # that way the script doesn't need the password + git clone -b main https://github.com/subsurface/nightly-builds + cd nightly-builds + git remote set-url origin "$url" + git push origin main + cd .. + bash -x subsurface/scripts/get-or-create-build-nr.sh ${{ github.sha }} + latest=$(> $GITHUB_OUTPUT + - name: create release name id: tag run: | @@ -60,7 +76,7 @@ jobs: if: github.event_name == 'push' uses: softprops/action-gh-release@v1 with: - tag_name: v${{ steps.date.outputs.today }}.${{ github.run_number }} + tag_name: v${{ steps.date.outputs.today }}.${{ steps.build_nr.outputs.latest }} repository: subsurface/nightly-builds token: ${{ secrets.NIGHTLY_BUILDS }} prerelease: false diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index b8b16f82b..22355fb3d 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -13,6 +13,21 @@ jobs: steps: - name: checkout sources uses: actions/checkout@v1 + - name: atomically create or retrieve the build number + id: build_nr + run: | + cd .. # check out parallel to subsurface sources + url="https://subsurface:${{ secrets.NIGHTLY_BUILDS }}@github.com/subsurface/nightly-builds" + # the clone followed by the pointless push should verify that the password is stored in the config + # that way the script doesn't need the password + git clone -b main https://github.com/subsurface/nightly-builds + cd nightly-builds + git remote set-url origin "$url" + git push origin main + cd .. + bash -x subsurface/scripts/get-or-create-build-nr.sh ${{ github.sha }} + latest=$(> $GITHUB_OUTPUT - name: setup Homebrew run: brew install hidapi libxslt libjpg libmtp create-dmg confuse - name: set our Qt build @@ -49,7 +64,7 @@ jobs: if: github.event_name == 'push' uses: softprops/action-gh-release@v1 with: - tag_name: v${{ steps.date.outputs.today }}.${{ github.run_number }} + tag_name: v${{ steps.date.outputs.today }}.${{ steps.build_nr.outputs.latest }} repository: subsurface/nightly-builds token: ${{ secrets.NIGHTLY_BUILDS }} prerelease: false diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index b78249976..dd4c28223 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -17,6 +17,22 @@ jobs: - name: checkout sources uses: actions/checkout@v1 + - name: atomically create or retrieve the build number + id: build_nr + run: | + cd .. # check out parallel to subsurface sources + url="https://subsurface:${{ secrets.NIGHTLY_BUILDS }}@github.com/subsurface/nightly-builds" + # the clone followed by the pointless push should verify that the password is stored in the config + # that way the script doesn't need the password + git clone -b main https://github.com/subsurface/nightly-builds + cd nightly-builds + git remote set-url origin "$url" + git push origin main + cd .. + bash -x subsurface/scripts/get-or-create-build-nr.sh ${{ github.sha }} + latest=$(> $GITHUB_OUTPUT + - name: create release name id: tag run: | @@ -67,7 +83,7 @@ jobs: if: github.event_name == 'push' uses: softprops/action-gh-release@v1 with: - tag_name: v${{ steps.date.outputs.today }}.${{ github.run_number }} + tag_name: v${{ steps.date.outputs.today }}.${{ steps.build_nr.outputs.latest }} repository: subsurface/nightly-builds token: ${{ secrets.NIGHTLY_BUILDS }} prerelease: false diff --git a/scripts/get-or-create-build-nr.sh b/scripts/get-or-create-build-nr.sh new file mode 100644 index 000000000..14f1ce894 --- /dev/null +++ b/scripts/get-or-create-build-nr.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# this is comically complicated - why does GitHub not have a monotonic number +# that tracks how many times any action was kicked off? Or an atomic way to update a variable? +# So we use the fact that git itself does a great job of preventing us from overwriting an +# existing branch and abuse that to create atomicity + +SHA_BRANCH="branch-for-$1" + +# first - make sure git is configured so we can do stuff +git config --global user.email "ci@subsurface-divelog.org" +git config --global user.name "Subsurface CI" + +# next, clone the release repo +[ -d nightly-builds ] || git clone https://github.com/subsurface/nightly-builds +cd nightly-builds + +# this is from the main branch, so this should be the PREVIOUS build number +latest=$( latest-subsurface-buildnumber + git commit -a -m "record build number for this SHA" + + # now comes the moment of truth - are we the first one? + # the push will succeed for exactly one of the workflows + if git push https://github.com/subsurface/nightly-builds $SHA_BRANCH + then + # yay - we win! now let's make sure that we remember this number for next time + git checkout main + echo $latest > latest-subsurface-buildnumber + git commit -a -m "record latest build number in main branch" + if ! git push https://github.com/subsurface/nightly-builds main + then + echo "push to main failed - we'll lose monotonic property" + exit -1 + fi + else + # someone else was faster - get the number they wrote + git checkout main + git branch -D $SHA_BRANCH + if ! git checkout -b $SHA_BRANCH + then + echo "push to $SHA_BRANCH failed, but switching to it failed as well" + exit -2 + fi + latest=$(