diff --git a/.github/workflows/release.yml b/.github/workflows/release-check.yml similarity index 51% rename from .github/workflows/release.yml rename to .github/workflows/release-check.yml index f50228eae..11d17f144 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release-check.yml @@ -1,25 +1,39 @@ -name: Release +name: Release Checker on: - release: - types: [published] + pull_request_target: + paths: ["Cargo.toml"] + types: [ opened, synchronize, reopened, labeled, unlabeled ] + workflow_dispatch: -env: - RUSTFLAGS: -Dwarnings +permissions: + contents: write + pull-requests: write + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: - release: + release-check: + uses: ipdxco/unified-github-workflows/.github/workflows/release-check.yml@v1.0 + with: + sources: '["Cargo.toml"]' + upload-release-assets: + needs: [release-check] + if: fromJSON(needs.release-check.outputs.json)['Cargo.toml'] runs-on: ubuntu-latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CARGO_INCREMENTAL: 0 CACHE_SKIP_SAVE: ${{ matrix.push == '' || matrix.push == 'false' }} + RUSTFLAGS: -Dwarnings strategy: matrix: network: [ 'mainnet', 'caterpillarnet', 'butterflynet', 'calibrationnet', 'devnet', 'testing', 'testing-fake-proofs' ] steps: - name: Checking out - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setting up cache uses: pl-strflt/rust-sccache-action@v1 env: @@ -31,10 +45,10 @@ jobs: BUILD_FIL_NETWORK: ${{ matrix.network }} run: | cargo run --locked -- -o output/builtin-actors.car - - name: Publishing release and uploading bundle to GitHub + - name: Upload release assets to GitHub Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITHUB_REF: ${{ github.ref }} + GITHUB_RELEASE_URL: ${{ fromJSON(needs.release-check.outputs.json)['Cargo.toml'].url }} BUILD_FIL_NETWORK: ${{ matrix.network }} run: | - ./scripts/publish-release.sh + ./scripts/upload-release-assets.sh diff --git a/.github/workflows/releaser.yml b/.github/workflows/releaser.yml new file mode 100644 index 000000000..a95658ea4 --- /dev/null +++ b/.github/workflows/releaser.yml @@ -0,0 +1,21 @@ +name: Releaser + +on: + push: + paths: ["Cargo.toml"] + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: ${{ github.workflow }}-${{ github.sha }} + cancel-in-progress: true + +jobs: + releaser: + uses: ipdxco/unified-github-workflows/.github/workflows/releaser.yml@v1.0 + with: + sources: '["Cargo.toml"]' + secrets: + UCI_GITHUB_TOKEN: ${{ secrets.UCI_GITHUB_TOKEN }} diff --git a/README.md b/README.md index bd65a6e09..19af554a6 100644 --- a/README.md +++ b/README.md @@ -82,14 +82,7 @@ Precompiled actor bundles are provided as [release binaries][releases] in this r [`fil_builtin_actors_bundle`](https://crates.io/crates/fil_builtin_actors_bundle) crate on [crates.io](https://crates.io) will not be updated. -## Releasing - -We release all actors, the runtime, and the state abstraction at the same time by: - -1. Changing the `workspace.package.version` in the top-level `Cargo.toml` file. -2. Creating a [release][releases] in GitHub. - -This will trigger an automatic bundle-build by GitHub CI, and the generated bundles will be attached to the GitHub release. +## [Releasing](RELEASE.md) ## Instructions for client implementations diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 000000000..0af761a59 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,29 @@ +# Release Process + +This document describes the process for releasing a new version of the `builtin-actors` project. + +## Current State + +1. Create a pull request which updates the `workspace.package.version` in the [top-level `Cargo.toml` file](https://github.com/filecoin-project/builtin-actors/blob/master/Cargo.toml). + - Title the PR `chore: release X.Y.Z` +2. On pull request creation, a [Release Checker](.github/workflows/release-check.yml) workflow will run. It will perform the following actions: + 1. Extract the version from the top-level `Cargo.toml` file. + 2. Check if a git tag for the version already exists. Continue only if it does not. + 3. Create a draft GitHub release with the version as the tag. (A git tag with this version string will be created when the release is published.) + 4. Comment on the pull request with a link to the draft release. + 5. Build `builtin-actors.car`s for various networks. + 6. Generate checksums for the built `builtin-actors.car`s. + 7. Upload the built `builtin-actors.car`s and checksums as assets to the draft release (replace any existing assets with the same name). +3. On pull request merge, a [Releaser](.github/workflows/release.yml) workflow will run. It will perform the following actions: + 1. Extract the version from the top-level `Cargo.toml` 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. + +## Known Limitations + +1. If one pushes an update to the `workspace.package.version` in the top-level `Cargo.toml` 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 [upload-release-assets.sh](scripts/upload-release-assets.sh) script to upload the missing assets. diff --git a/scripts/publish-release.sh b/scripts/upload-release-assets.sh similarity index 60% rename from scripts/publish-release.sh rename to scripts/upload-release-assets.sh index 12f6a633a..58c636f40 100755 --- a/scripts/publish-release.sh +++ b/scripts/upload-release-assets.sh @@ -12,9 +12,9 @@ if [ -z "$GITHUB_TOKEN" ]; then die "no GITHUB_TOKEN" fi -# make sure we have a release tag set -if [ -z "$GITHUB_REF" ]; then - die "no GITHUB_REF" +# make sure we have a release url set +if [ -z "$GITHUB_RELEASE_URL" ]; then + die "no GITHUB_RELEASE_URL" fi # make sure we have a target set @@ -28,8 +28,6 @@ release_target=builtin-actors-${BUILD_FIL_NETWORK}.car release_target_hash=builtin-actors-${BUILD_FIL_NETWORK}.sha256 release_file=output/$release_target release_file_hash=output/$release_target_hash -# the ref is of the form refs/tags/; drop the prefix to get the actual release tag -release_tag="${GITHUB_REF:10}" # prepare artifacts pushd output @@ -45,16 +43,27 @@ REPO="builtin-actors" __release_response=` curl \ --header "Authorization: token $GITHUB_TOKEN" \ - "https://api.github.com/repos/$ORG/$REPO/releases/tags/$release_tag" + "$GITHUB_RELEASE_URL" ` __release_id=`echo $__release_response | jq '.id'` if [ "$__release_id" = "null" ]; then - echo "release $release_tag does not exist" + echo "release does not exist" exit 1 fi __release_upload_url=`echo $__release_response | jq -r '.upload_url' | cut -d'{' -f1` +__release_target_asset=`echo $__release_response | jq -r ".assets | .[] | select(.name == \"$release_target\")"` + +if [ -n "$__release_target_asset" ]; then + echo "deleting $release_target" + __release_target_asset_url=`echo $__release_target_asset | jq -r '.url'` + curl \ + --request DELETE \ + --header "Authorization: token $GITHUB_TOKEN" \ + "$__release_target_asset_url" +fi + echo "uploading $release_target" curl \ --request POST \ @@ -63,6 +72,17 @@ curl \ --data-binary "@$release_file" \ "$__release_upload_url?name=$release_target" +__release_target_hash_asset=`echo $__release_response | jq -r ".assets | .[] | select(.name == \"$release_target_hash\")"` + +if [ -n "$__release_target_hash_asset" ]; then + echo "deleting $release_target_hash" + __release_target_hash_asset_url=`echo $__release_target_hash_asset | jq -r '.url'` + curl \ + --request DELETE \ + --header "Authorization: token $GITHUB_TOKEN" \ + "$__release_target_hash_asset_url" +fi + echo "uploading $release_target_hash" curl \ --request POST \