Skip to content

Commit a314ba0

Browse files
committed
chore(workflow): overhaul CI for release management
- Renamed workflow to "Release CI" and added jobs for versioning, changelog generation, and building binaries. - Implemented release-please action for automated release PRs and asset uploads. - Enhanced test job to ensure successful builds before releases. - Added cross-compilation support for different targets and packaging of release binaries.
1 parent 7439179 commit a314ba0

1 file changed

Lines changed: 154 additions & 4 deletions

File tree

.github/workflows/rust.yml

Lines changed: 154 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,171 @@
1-
name: Build and Test
1+
name: Release CI
22

33
on:
44
push:
55
branches: ["master"]
6-
pull_request:
7-
branches: ["master"]
6+
7+
# Grant permissions for release-please to create PRs, write releases, and commit files
8+
permissions:
9+
contents: write
10+
pull-requests: write
11+
12+
concurrency:
13+
group: ${{ github.workflow }}-${{ github.ref }}
14+
cancel-in-progress: true
815

916
env:
1017
CARGO_TERM_COLOR: always
18+
# IMPORTANT: Set this to the name of your crate as defined in Cargo.toml
19+
# This is used by release-please and for naming artifacts.
20+
CRATE_NAME: rust-commit-tracker
1121

1222
jobs:
13-
build:
23+
# This job handles versioning, changelog generation, and creating Release PRs.
24+
# When a Release PR is merged, it creates the Git tag and GitHub Release.
25+
release-please:
1426
runs-on: ubuntu-latest
27+
outputs:
28+
release_created: ${{ steps.release.outputs.release_created }}
29+
tag_name: ${{ steps.release.outputs.tag_name }}
30+
# 'version' output by release-please is the raw version, e.g., "1.2.3"
31+
# 'tag_name' is typically "v1.2.3"
32+
version: ${{ steps.release.outputs.version }}
33+
upload_url: ${{ steps.release.outputs.upload_url }} # URL for uploading release assets
34+
steps:
35+
- uses: google-github-actions/release-please-action@v4
36+
id: release
37+
with:
38+
# Tells release-please this is a Rust project.
39+
# It will look for Cargo.toml and update the version there.
40+
release-type: rust
41+
# Explicitly provide the package name if Cargo.toml is not at the root,
42+
# or if you want to be very specific.
43+
44+
# Optional: If you want minor bumps for 'feat' before v1.0.0
45+
# bump-minor-pre-major: true
46+
# Optional: If you want patch bumps for 'fix' before v1.0.0
47+
# bump-patch-for-minor-pre-major: true
48+
# Optional: Customize the path to your changelog
49+
# changelog-path: CHANGELOG.md
1550

51+
# Your existing test job - good to keep!
52+
# release-please will create PRs based on commits to master.
53+
# Ensure your master branch is protected and requires tests to pass.
54+
test:
55+
runs-on: ubuntu-latest
56+
# You might want this to run on PRs to master as well,
57+
# especially for the Release PRs created by release-please.
58+
# on:
59+
# pull_request:
60+
# branches: ["master"]
1661
steps:
1762
- uses: actions/checkout@v4
63+
- name: Install Rust toolchain
64+
uses: dtolnay/rust-toolchain@stable
1865
- name: Build
1966
run: cargo build --verbose
2067
- name: Run tests
2168
run: cargo test --verbose
69+
70+
# This job builds the binaries for different targets.
71+
# It only runs IF a release was actually created by release-please (i.e., Release PR merged).
72+
build-binaries:
73+
needs: [release-please, test] # Ensure tests pass and release is initiated
74+
if: needs.release-please.outputs.release_created == 'true'
75+
runs-on: ${{ matrix.os }} # Use the OS specified in the matrix
76+
strategy:
77+
matrix:
78+
include:
79+
- target: x86_64-pc-windows-gnu
80+
os: ubuntu-latest # Cross-compile Windows on Linux
81+
asset_name_suffix: .exe
82+
archive_format: zip
83+
- target: x86_64-unknown-linux-gnu
84+
os: ubuntu-latest
85+
asset_name_suffix: ""
86+
archive_format: tar.gz
87+
- target: x86_64-apple-darwin
88+
os: macos-latest # Build macOS on macOS
89+
asset_name_suffix: ""
90+
archive_format: tar.gz
91+
steps:
92+
- uses: actions/checkout@v4
93+
# No need for fetch-depth: 0 here, building from the release commit.
94+
95+
- name: Install Rust toolchain for target
96+
uses: dtolnay/rust-toolchain@stable
97+
with:
98+
toolchain: stable # Or a specific version
99+
targets: ${{ matrix.target }}
100+
101+
- name: Install cross-compilation tools (for Windows target on Linux)
102+
if: matrix.target == 'x86_64-pc-windows-gnu' && runner.os == 'Linux'
103+
run: |
104+
sudo apt-get update -y
105+
sudo apt-get install -y gcc-mingw-w64-x86-64
106+
107+
- name: Build release binary
108+
run: |
109+
# Set linker for windows cross-compilation if on Linux runner
110+
if [ "${{ matrix.target }}" = "x86_64-pc-windows-gnu" ] && [ "${{ runner.os }}" = "Linux" ]; then
111+
export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc
112+
fi
113+
cargo build --release --target ${{ matrix.target }} --verbose
114+
115+
- name: Determine Asset Names
116+
id: asset_names
117+
shell: bash # Ensure bash is used for consistency
118+
run: |
119+
# Use the CRATE_NAME from env for the binary's base name
120+
local_crate_name="${{ env.CRATE_NAME }}"
121+
# Use the tag_name from release-please for versioning in the archive
122+
local_tag_name="${{ needs.release-please.outputs.tag_name }}"
123+
124+
binary_filename="${local_crate_name}${{ matrix.asset_name_suffix }}"
125+
archive_filename="${local_crate_name}-${local_tag_name}-${{ matrix.target }}.${{ matrix.archive_format }}"
126+
127+
echo "binary_path=target/${{ matrix.target }}/release/${binary_filename}" >> $GITHUB_OUTPUT
128+
echo "archive_path=dist/${archive_filename}" >> $GITHUB_OUTPUT
129+
echo "asset_upload_name=${archive_filename}" >> $GITHUB_OUTPUT
130+
echo "packaged_binary_name=${binary_filename}" >> $GITHUB_OUTPUT
131+
132+
- name: Package binary
133+
shell: bash # Ensure bash is used
134+
run: |
135+
mkdir -p dist
136+
cp "${{ steps.asset_names.outputs.binary_path }}" "dist/${{ steps.asset_names.outputs.packaged_binary_name }}"
137+
cd dist
138+
if [ "${{ matrix.archive_format }}" = "zip" ]; then
139+
zip -r "${{ steps.asset_names.outputs.asset_upload_name }}" "${{ steps.asset_names.outputs.packaged_binary_name }}"
140+
else
141+
tar -czf "${{ steps.asset_names.outputs.asset_upload_name }}" "${{ steps.asset_names.outputs.packaged_binary_name }}"
142+
fi
143+
cd .. # Go back to the original directory
144+
145+
- name: Upload Release Asset
146+
uses: actions/upload-release-asset@v1
147+
env:
148+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
149+
with:
150+
upload_url: ${{ needs.release-please.outputs.upload_url }}
151+
asset_path: ${{ steps.asset_names.outputs.archive_path }}
152+
asset_name: ${{ steps.asset_names.outputs.asset_upload_name }}
153+
asset_content_type: application/octet-stream # Or specific types like application/zip
154+
155+
# Optional: Job to publish your crate to crates.io
156+
publish-crate:
157+
needs: [release-please, test] # Depends on a release being created and tests passing
158+
if: needs.release-please.outputs.release_created == 'true'
159+
runs-on: ubuntu-latest
160+
steps:
161+
- uses: actions/checkout@v4
162+
with:
163+
# Checkout the specific commit that was tagged for this release
164+
ref: ${{ needs.release-please.outputs.tag_name }}
165+
166+
- name: Install Rust toolchain
167+
uses: dtolnay/rust-toolchain@stable
168+
169+
- name: Publish to crates.io
170+
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
171+
# Ensure CARGO_REGISTRY_TOKEN is set as a secret in your GitHub repository settings

0 commit comments

Comments
 (0)