Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions .github/workflows/releaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,111 @@ jobs:
sources: '["version.json"]'
secrets:
UCI_GITHUB_TOKEN: ${{ secrets.UCI_GITHUB_TOKEN }}

validate-and-build-missing-assets:
needs: [releaser]
if: fromJSON(needs.releaser.outputs.json)['version.json']
name: Validate release assets (${{ 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@v4
with:
submodules: recursive
- uses: ./.github/actions/configure-environment
- if: runner.os == 'macOS'
run: |
rustup target add x86_64-apple-darwin
cargo fetch
working-directory: rust
- name: Check and build missing release assets
env:
GITHUB_TOKEN: ${{ github.token }}
RELEASE_TAG: >-
${{ fromJSON(needs.releaser.outputs.json)['version.json'].tag }}
RELEASE_ID: >-
${{ fromJSON(needs.releaser.outputs.json)['version.json'].id }}
run: |
# Get release information
RELEASE_URL="https://api.github.com/repos"
RELEASE_URL="$RELEASE_URL/${{ github.repository }}/releases"
RELEASE_INFO=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
"$RELEASE_URL/$RELEASE_ID")

if [ "$(echo $RELEASE_INFO | jq '.id')" = "null" ]; then
Copy link
Preview

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition checks for the string 'null' but jq returns the literal null value. This should be if [ "$(echo $RELEASE_INFO | jq '.id')" = "null" ]; then or better yet, use if [ "$(echo $RELEASE_INFO | jq -r '.id')" = "null" ]; then to get the raw output.

Suggested change
if [ "$(echo $RELEASE_INFO | jq '.id')" = "null" ]; then
if [ "$(echo $RELEASE_INFO | jq -r '.id')" = "null" ]; then

Copilot uses AI. Check for mistakes.

echo "Release not found for ID $RELEASE_ID"
exit 1
fi

echo "Checking assets for release: $RELEASE_TAG"

# Determine what asset this runner should build
REPOSITORY_NAME=${GITHUB_REPOSITORY##*/}

if [ "$RUNNER_OS" = "Linux" ] && [ "$RUNNER_ARCH" = "X64" ]; then
EXPECTED_ASSET="${REPOSITORY_NAME}-Linux-x86_64-standard.tar.gz"
BUILD_CMD="./scripts/build-release.sh build --verbose"
BUILD_CMD="$BUILD_CMD --no-default-features"
BUILD_CMD="$BUILD_CMD --features multicore-sdr,opencl,blst-portable"
elif [ "$RUNNER_OS" = "Linux" ] && [ "$RUNNER_ARCH" = "ARM64" ]; then
EXPECTED_ASSET="${REPOSITORY_NAME}-Linux-aarch64-standard.tar.gz"
BUILD_CMD="./scripts/build-release.sh build --verbose"
BUILD_CMD="$BUILD_CMD --no-default-features"
BUILD_CMD="$BUILD_CMD --features multicore-sdr,opencl,blst-portable"
elif [ "$RUNNER_OS" = "macOS" ]; then
EXPECTED_ASSET="${REPOSITORY_NAME}-Darwin-standard.tar.gz"
BUILD_CMD="./scripts/build-release.sh lipo --verbose"
BUILD_CMD="$BUILD_CMD --no-default-features"
BUILD_CMD="$BUILD_CMD --features multicore-sdr,opencl,blst-portable"
else
echo "Unknown runner configuration: $RUNNER_OS $RUNNER_ARCH"
exit 1
fi

# Check if this asset already exists
asset_exists=$(echo $RELEASE_INFO | jq -r \
".assets[] | select(.name == \"$EXPECTED_ASSET\") | .name")

if [ -n "$asset_exists" ]; then
Comment on lines +92 to +94
Copy link
Preview

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The asset existence check could be simplified and made more robust by using jq's any() function: asset_exists=$(echo $RELEASE_INFO | jq -r '.assets | any(.name == \"'$EXPECTED_ASSET'\")') and then check for 'true'/'false' instead of checking if the variable is non-empty.

Suggested change
".assets[] | select(.name == \"$EXPECTED_ASSET\") | .name")
if [ -n "$asset_exists" ]; then
".assets | any(.name == \"$EXPECTED_ASSET\")")
if [ "$asset_exists" = "true" ]; then

Copilot uses AI. Check for mistakes.

echo "Asset $EXPECTED_ASSET already exists - skipping"
exit 0
fi

echo "Asset $EXPECTED_ASSET is missing - building it"

# Build the asset
cd rust

if [ "$RUNNER_OS" = "Linux" ]; then
TARBALL_PATH="/tmp/$EXPECTED_ASSET"

$BUILD_CMD
./scripts/package-release.sh $TARBALL_PATH

# Upload using the publish-release script
API_URL="https://api.github.com/repos"
RELEASE_URL="$API_URL/${{ github.repository }}/releases/$RELEASE_ID"
export GITHUB_RELEASE_URL="$RELEASE_URL"
./scripts/publish-release.sh $TARBALL_PATH $EXPECTED_ASSET

elif [ "$RUNNER_OS" = "macOS" ]; then
TARBALL_PATH="/tmp/$EXPECTED_ASSET"

$BUILD_CMD
./scripts/package-release.sh $TARBALL_PATH

# Upload using the publish-release script
API_URL="https://api.github.com/repos"
RELEASE_URL="$API_URL/${{ github.repository }}/releases/$RELEASE_ID"
export GITHUB_RELEASE_URL="$RELEASE_URL"
./scripts/publish-release.sh $TARBALL_PATH $EXPECTED_ASSET
fi
Comment on lines +104 to +127
Copy link
Preview

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The Linux and macOS build/upload logic is identical and duplicated. This should be extracted to eliminate code duplication - the conditional logic could be moved after the platform-specific asset name and build command determination.

Copilot uses AI. Check for mistakes.


echo "Successfully built and uploaded: $EXPECTED_ASSET"
8 changes: 6 additions & 2 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,20 @@ This document describes the process for releasing a new version of the `filecoin
4. Comment on the pull request with a link to the draft release.
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).
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. **Validate that all expected release assets are present.** If any assets are missing, build and upload them automatically:
- Linux (X64) standard: `filecoin-ffi-Linux-x86_64-standard.tar.gz`
- Linux (ARM64) standard: `filecoin-ffi-Linux-aarch64-standard.tar.gz`
- MacOS universal standard: `filecoin-ffi-Darwin-standard.tar.gz`

## 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.
1. ~~Add a check to the [Releaser](.github/workflows/releaser.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.~~ **✅ IMPLEMENTED** - The Releaser workflow now automatically validates and builds missing release assets.