diff --git a/.github/actions/upload-release-assets/action.yml b/.github/actions/upload-release-assets/action.yml index 43184593..71636b3b 100644 --- a/.github/actions/upload-release-assets/action.yml +++ b/.github/actions/upload-release-assets/action.yml @@ -8,13 +8,17 @@ inputs: ref: description: The release ref required: true + force: + description: Force upload + required: false + default: 'false' runs: using: 'composite' steps: - run: echo "Running on $RUNNER_OS $RUNNER_ARCH" shell: bash - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: ref: ${{ inputs.ref }} submodules: recursive @@ -30,16 +34,22 @@ runs: env: GITHUB_TOKEN: ${{ github.token }} GITHUB_RELEASE_URL: ${{ github.api_url }}/repos/${{ github.repository }}/releases/${{ inputs.id }} + INPUTS_FORCE: ${{ inputs.force }} run: | REPOSITORY_NAME=${GITHUB_REPOSITORY##*/} - TARBALL_PATH="/tmp/${REPOSITORY_NAME}-$(uname)-$(uname -m)-standard.tar.gz" RELEASE_NAME="${REPOSITORY_NAME}-$(uname)-$(uname -m)-standard" + TARBALL_PATH="/tmp/${RELEASE_NAME}.tar.gz" + + # Note: If assets should not be overwritten, exit early if they already exist + if [[ "$INPUTS_FORCE" == 'false' && "$(./scripts/check-release.sh $TARBALL_PATH)" == 'true' ]]; then + exit 0 + fi # Note: the blst dependency uses the portable configuration for maximum compatibility ./scripts/build-release.sh build --verbose --no-default-features --features multicore-sdr,opencl,blst-portable ./scripts/package-release.sh $TARBALL_PATH - ./scripts/publish-release.sh $TARBALL_PATH $RELEASE_NAME + ./scripts/publish-release.sh $TARBALL_PATH working-directory: rust shell: bash - if: runner.os == 'Linux' @@ -59,15 +69,21 @@ runs: env: GITHUB_TOKEN: ${{ github.token }} GITHUB_RELEASE_URL: ${{ github.api_url }}/repos/${{ github.repository }}/releases/${{ inputs.id }} + INPUTS_FORCE: ${{ inputs.force }} run: | REPOSITORY_NAME=${GITHUB_REPOSITORY##*/} RELEASE_NAME="${REPOSITORY_NAME}-$(uname)-standard" TARBALL_PATH="/tmp/${RELEASE_NAME}.tar.gz" + # Note: If assets should not be overwritten, exit early if they already exist + if [[ "$INPUTS_FORCE" == 'false' && "$(./scripts/check-release.sh $TARBALL_PATH)" == 'true' ]]; then + exit 0 + fi + # Note: the blst dependency uses the portable configuration for maximum compatibility ./scripts/build-release.sh lipo --verbose --no-default-features --features multicore-sdr,opencl,blst-portable ./scripts/package-release.sh $TARBALL_PATH - ./scripts/publish-release.sh $TARBALL_PATH $RELEASE_NAME + ./scripts/publish-release.sh $TARBALL_PATH working-directory: rust shell: bash diff --git a/.github/workflows/release-check.yml b/.github/workflows/release-check.yml index 2a995a86..c4e6ad83 100644 --- a/.github/workflows/release-check.yml +++ b/.github/workflows/release-check.yml @@ -29,7 +29,8 @@ jobs: runner: ['ubuntu-latest', ['self-hosted', 'linux', 'arm64', 'xlarge'], 'macos-latest'] fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: ./.github/actions/upload-release-assets with: id: ${{ fromJSON(needs.release-check.outputs.json)['version.json'].id }} + force: true diff --git a/.github/workflows/releaser.yml b/.github/workflows/releaser.yml index a2b2a044..5d807504 100644 --- a/.github/workflows/releaser.yml +++ b/.github/workflows/releaser.yml @@ -19,3 +19,18 @@ jobs: sources: '["version.json"]' secrets: UCI_GITHUB_TOKEN: ${{ secrets.UCI_GITHUB_TOKEN }} + upload-release-assets: + needs: [releaser] + if: fromJSON(needs.releaser.outputs.json)['version.json'] + name: Publish the static library (${{ matrix.runner }}) + runs-on: ${{ matrix.runner }} + strategy: + matrix: + runner: ['ubuntu-latest', ['self-hosted', 'linux', 'arm64', 'xlarge'], 'macos-latest'] + fail-fast: false + steps: + - uses: actions/checkout@v6 + - uses: ./.github/actions/upload-release-assets + with: + id: ${{ fromJSON(needs.releaser.outputs.json)['version.json'].id }} + force: false diff --git a/.github/workflows/upload-release-assets.yml b/.github/workflows/upload-release-assets.yml index 7e1d425c..b5a62329 100644 --- a/.github/workflows/upload-release-assets.yml +++ b/.github/workflows/upload-release-assets.yml @@ -9,6 +9,11 @@ on: ref: description: The release ref (e.g. refs/tags/v1.34.0) required: true + force: + type: boolean + description: Whether the assets should be overwritten if they already exist + required: false + default: false permissions: contents: write @@ -27,8 +32,9 @@ jobs: runner: ['ubuntu-latest', ['self-hosted', 'linux', 'arm64', 'xlarge'], 'macos-latest'] fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: ./.github/actions/upload-release-assets with: id: ${{ inputs.id }} ref: ${{ inputs.ref }} + force: ${{ inputs.force }} diff --git a/RELEASE.md b/RELEASE.md index 931e8673..f907e576 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -14,17 +14,17 @@ This document describes the process for releasing a new version of the `filecoin 5. Build the project for Linux (X64), Linux (ARM64), and MacOS. 7. Upload the built assets to the draft release (replace any existing assets with the same name). - If for some reason asset uploading fails, the [Upload Release Assets](.github/workflows/upload-release-assets.yml) workflow can be manually run. -3. On pull request merge, a [Releaser](.github/workflows/release.yml) workflow will run. It will perform the following actions: +3. On pull request merge, a [Releaser](.github/workflows/releaser.yml) workflow will run. It will perform the following actions: 1. Extract the version from the top-level `version.json` file. 2. Check if a git tag for the version already exists. Continue only if it does not. 3. Check if a draft GitHub release with the version as the tag exists. 4. If the draft release exists, publish it. Otherwise, create and publish a new release with the version as the git tag. Publishing the release creates the git tag. + 5. Check if the release contains Linux (X64), Linux (ARM64), and MacOS assets. If not: + 1. Build the missing assets. + 2. Upload the built assets to the release. + - If for some reason asset uploading fails, the [Upload Release Assets](.github/workflows/upload-release-assets.yml) workflow can be manually run. + ## Known Limitations 1. If one pushes an update to the `version` in the top-level `version.json` file without creating a pull request, the Release Checker workflow will not run. Hence, the release assets will not be automatically built and uploaded. - -## Possible Improvements - -1. Add a check to the [Releaser](.github/workflows/release.yml) workflow to ensure that the created/published release contains the expected assets. If it does not, create them and run the [publish-release.sh](rust/scripts/publish-release.sh) script to upload the missing assets. - - In the interim, if for some reason asset uploading fails, the [Upload Release Assets](.github/workflows/upload-release-assets.yml) workflow can be manually run. diff --git a/rust/scripts/check-release.sh b/rust/scripts/check-release.sh new file mode 100755 index 00000000..cc318ff1 --- /dev/null +++ b/rust/scripts/check-release.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +set -Exeuo pipefail + +main() { + if [[ -z "$1" ]] + then + (>&2 echo '[check-release/main] Error: script requires a release (gzipped) tarball path, e.g. "/tmp/filecoin-ffi-Darwin-standard.tar.tz"') + exit 1 + fi + + # make sure we have a token set, api requests won't work otherwise + if [ -z $GITHUB_TOKEN ]; then + (>&2 echo "[check-release/main] \$GITHUB_TOKEN not set, check failed") + exit 1 + fi + + # make sure we have a release url set + if [ -z "$GITHUB_RELEASE_URL" ]; then + (>&2 echo "[check-release/main] \$GITHUB_RELEASE_URL not set, check failed") + exit 1 + fi + + local __release_file=$1 + local __release_url="${GITHUB_RELEASE_URL}" + local __release_target="$(basename $__release_file)" + + # see if the release already exists by tag + local __release_response=` + curl \ + --header "Authorization: token $GITHUB_TOKEN" \ + "$__release_url" + ` + + local __release_id=`echo $__release_response | jq '.id'` + + if [ "$__release_id" = "null" ]; then + (>&2 echo '[check-release/main] release does not exist') + exit 1 + fi + + local __release_target_asset=`echo $__release_response | jq -r ".assets | .[] | select(.name == \"$__release_target\")"` + + if [ -n "$__release_target_asset" ]; then + (>&2 echo '[check-release/main] release asset exists') + echo "true" + else + (>&2 echo '[check-release/main] release asset does not exist') + echo "false" + fi +} + +main "$@"; exit diff --git a/rust/scripts/publish-release.sh b/rust/scripts/publish-release.sh index 231cd7e5..fcf13301 100755 --- a/rust/scripts/publish-release.sh +++ b/rust/scripts/publish-release.sh @@ -9,16 +9,6 @@ main() { exit 1 fi - if [[ -z "$2" ]] - then - (>&2 echo '[publish-release/main] Error: script requires a release name, e.g. "filecoin-ffi-Darwin-standard" or "filecoin-ffi-Linux-standard"') - exit 1 - fi - - local __release_file=$1 - local __release_url="${GITHUB_RELEASE_URL}" - local __release_target="$(basename $__release_file)" - # make sure we have a token set, api requests won't work otherwise if [ -z $GITHUB_TOKEN ]; then (>&2 echo "[publish-release/main] \$GITHUB_TOKEN not set, publish failed") @@ -31,6 +21,10 @@ main() { exit 1 fi + local __release_file=$1 + local __release_url="${GITHUB_RELEASE_URL}" + local __release_target="$(basename $__release_file)" + # see if the release already exists by tag local __release_response=` curl \ @@ -45,7 +39,7 @@ main() { exit 1 fi - __release_target_asset=`echo $__release_response | jq -r ".assets | .[] | select(.name == \"$__release_target\")"` + local __release_target_asset=`echo $__release_response | jq -r ".assets | .[] | select(.name == \"$__release_target\")"` if [ -n "$__release_target_asset" ]; then (>&2 echo "[publish-release/main] $__release_target_asset already exists, deleting")