GitHub Workflows – Rust
So this first version, (helped by Claude) persistently did the build but failed to do the release…..
permissions:
contents: write
actions: write
name: Build and Release Rust Binary
on:
push:
branches: [main]
tags:
- 'v*'
pull_request:
branches: [main]
jobs:
build:
name: Build on ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
artifact_name: rmcp_nettools
archive_name: rmcp_nettools.linux.tar.gz
- os: windows-latest
artifact_name: rmcp_nettools.exe
archive_name: rmcp_nettools.windows.zip
- os: macos-latest
artifact_name: rmcp_nettools
archive_name: rmcp_nettools.macos.tar.gz
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Build
uses: actions-rs/cargo@v1
with:
command: build
args: --release
- name: List target directory (debug)
run: ls -lh target/release
shell: bash
- name: Compress Binary (Unix)
if: runner.os != 'Windows'
run: |
cd target/release
tar -czvf "${{ matrix.archive_name }}" "${{ matrix.artifact_name }}"
- name: Compress Binary (Windows)
if: runner.os == 'Windows'
run: |
Compress-Archive -Path "target/release/${{ matrix.artifact_name }}" -DestinationPath "target/release/${{ matrix.archive_name }}"
shell: pwsh
- name: Upload Build Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.archive_name }}
path: target/release/${{ matrix.archive_name }}
release:
name: Create and Upload Release
needs: [build]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- name: Download all workflow artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Display downloaded files
run: ls -R artifacts
- name: Create Release
id: create_release
uses: softprops/action-gh-release@v1
with:
files: |
artifacts/rmcp_nettools.linux.tar.gz/rmcp_nettools.linux.tar.gz
artifacts/rmcp_nettools.windows.zip/rmcp_nettools.windows.zip
artifacts/rmcp_nettools.macos.tar.gz/rmcp_nettools.macos.tar.gz
tag_name: ${{ github.ref_name }}
name: Release ${{ github.ref_name }}
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Then, after some more experimentation:
permissions:
contents: write
actions: write
name: Build and Release Rust Binary
on:
push:
branches: [main]
tags:
- 'v*'
pull_request:
branches: [main]
jobs:
build:
name: Build on ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
artifact_name: mcp-netval
archive_name: mcp-netval.linux.tar.gz
- os: windows-latest
artifact_name: mcp-netval.exe
archive_name: mcp-netval.windows.zip
- os: macos-latest
artifact_name: mcp-netval
archive_name: mcp-netval.macos.tar.gz
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Build
uses: actions-rs/cargo@v1
with:
command: build
args: --release
- name: List target directory (debug)
run: ls -lh target/release
shell: bash
- name: Compress Binary (Unix)
if: runner.os != 'Windows'
run: |
cd target/release
tar -czvf "${{ matrix.archive_name }}" "${{ matrix.artifact_name }}"
- name: Compress Binary (Windows)
if: runner.os == 'Windows'
run: |
Compress-Archive -Path "target/release/${{ matrix.artifact_name }}" -DestinationPath "target/release/${{ matrix.archive_name }}"
shell: pwsh
- name: Upload Build Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.archive_name }}
path: target/release/${{ matrix.archive_name }}
release:
name: Create and Upload Release
needs: [build]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Configure Git
run: |
git config user.name github-actions
git config user.email github-actions@github.com
- name: Generate tag
id: tag
run: |
TAG_NAME="v$(date +'%Y%m%d%H%M%S')"
echo "TAG_NAME=$TAG_NAME" >> $GITHUB_OUTPUT
git tag $TAG_NAME
git push origin $TAG_NAME
- name: Download all workflow artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Display downloaded files
run: ls -R artifacts
- name: Prepare release files
run: |
mkdir -p release_files
find artifacts -type f -exec cp {} release_files/ \;
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: release_files/*
tag_name: ${{ steps.tag.outputs.TAG_NAME }}
name: Release ${{ steps.tag.outputs.TAG_NAME }}
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
This complete workflow solution:
- Builds your Rust binary across Linux, Windows, and macOS
- Automatically creates a new tag with timestamp whenever code is pushed to the main branch
- Creates a GitHub release using that tag
- Uploads all built binaries to the release
Key changes I made:
- Changed the release job condition to run on main branch pushes:
if: github.ref == 'refs/heads/main'
- Added Git configuration for the automated commits
- Added a step to generate a unique tag with timestamp
- Simplified the file preparation with a find command that will handle nested directory structures
- Made sure the tag is both created locally and pushed to the remote repository
This approach eliminates the need to manually create tags. Now every push to your main branch will automatically create a new release with all your binaries attached.