From 94c47f64acddeb84abb76763238f4c07306eb7f2 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 | 31 ++++++++++------ .github/workflows/mac.yml | 26 +++++++++++--- .github/workflows/windows.yml | 46 +++++++++++------------- scripts/get-or-create-build-nr.sh | 60 +++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 41 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..829b25f67 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -17,14 +17,19 @@ jobs: - name: checkout sources uses: actions/checkout@v1 - - name: create release name - id: tag + - name: atomically create or retrieve the build number + id: build_nr run: | - export tag="" - export is_latest=false - if [ "${{ github.ref_type }}" = "tag" ] ; then tag="${{ github.ref_name }}" ; else tag="latest"; is_latest=true ; fi - echo "tag=${tag}" >> $GITHUB_OUTPUT - echo "is_latest=${is_latest}" >> $GITHUB_OUTPUT + 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 }} - name: run build id: build @@ -51,16 +56,20 @@ jobs: git config --global --add safe.directory ${SUBSURFACE_REPO_PATH}/libdivecomputer bash -x ./subsurface/packaging/android/qmake-build.sh - - name: Get current date - id: date - run: echo "today=$(date '+%Y-%m-%d')" >> $GITHUB_OUTPUT + - name: create version number + id: version_number + run: | + latest=$(cat ../nightly-builds/latest-subsurface-buildnumber) + today=$(date '+%Y-%m-%d') + version="$today.$latest" + echo "version=$version" >> $GITHUB_OUTPUT # only publish a 'release' on push events (those include merging a PR) - name: upload binaries 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.version_number.outputs.version }} repository: subsurface/nightly-builds token: ${{ secrets.NIGHTLY_BUILDS }} prerelease: false diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index b8b16f82b..3af8eda1a 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -13,6 +13,20 @@ 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 }} + - name: setup Homebrew run: brew install hidapi libxslt libjpg libmtp create-dmg confuse - name: set our Qt build @@ -40,16 +54,20 @@ jobs: echo "Created $IMG" echo "dmg=$IMG" >> $GITHUB_OUTPUT - - name: Get current date - id: date - run: echo "today=$(date '+%Y-%m-%d')" >> $GITHUB_OUTPUT + - name: create version number + id: version_number + run: | + latest=$(cat ../nightly-builds/latest-subsurface-buildnumber) + today=$(date '+%Y-%m-%d') + version="$today.$latest" + echo "version=$version" >> $GITHUB_OUTPUT # only publish a 'release' on push events (those include merging a PR) - name: upload binaries 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.version_number.outputs.version }} repository: subsurface/nightly-builds token: ${{ secrets.NIGHTLY_BUILDS }} prerelease: false diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index b78249976..0832ad393 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -17,29 +17,19 @@ jobs: - name: checkout sources uses: actions/checkout@v1 - - name: create release name - id: tag + - name: atomically create or retrieve the build number + id: build_nr run: | - export tag="" - export is_latest=false - if [ "${{ github.ref_type }}" = "tag" ] - then - tag="${{ github.ref_name }}" - else - tag="latest" - is_latest=true - fi - echo "tag=${tag}" >> $GITHUB_OUTPUT - echo "is_latest=${is_latest}" >> $GITHUB_OUTPUT - - - name: tag current version as latest if we don't have a tag - if: ${{ steps.tag.outputs.is_latest == 'true' }} - uses: rickstaa/action-create-tag@v1 - with: - tag: "latest" - tag_exists_error: false - force_push_tag: true - message: "latest commit to allow 'release' uploads" + 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 }} - name: get other dependencies env: @@ -58,16 +48,20 @@ jobs: bash -x subsurface/.github/workflows/scripts/windows-in-container-build.sh 2>&1 | tee build.log grep "Built target installer" build.log - - name: Get current date - id: date - run: echo "today=$(date '+%Y-%m-%d')" >> $GITHUB_OUTPUT + - name: create version number + id: version_number + run: | + latest=$(cat ../nightly-builds/latest-subsurface-buildnumber) + today=$(date '+%Y-%m-%d') + version="$today.$latest" + echo "version=$version" >> $GITHUB_OUTPUT # only publish a 'release' on push events (those include merging a PR) - name: upload binaries 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.version_number.outputs.version }} 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=$(