Skip to content

Commit b54fa18

Browse files
feat: Implement multi-platform builds and releases via GitHub Actions
This commit introduces changes to the GitHub Actions workflows to enable: 1. **Cross-Platform Builds**: The `build.yml` workflow now builds binaries for Linux (x86_64-unknown-linux-gnu), macOS (x86_64-apple-darwin), and Windows (x86_64-pc-windows-msvc). - Builds are triggered only on pushing a tag matching 'v*' (e.g., v1.0.0). - Each platform's binary is archived as a separate artifact (e.g., `codeinput-linux.zip`). 2. **Automated Releases**: A new `release` job in `build.yml` is created. - This job runs after all platform builds are successful. - It creates a GitHub Release named after the tag. - All platform-specific zipped binaries are uploaded as assets to this release. 3. **Cross-Platform Testing**: The `tests.yml` workflow has been updated to run tests on Ubuntu, macOS, and Windows, ensuring broader compatibility. These changes streamline the release process and provide you with pre-compiled binaries for major operating systems.
1 parent f50e0a3 commit b54fa18

File tree

2 files changed

+148
-39
lines changed

2 files changed

+148
-39
lines changed

.github/workflows/build.yml

Lines changed: 147 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,187 @@
1-
name: Build
1+
name: Build and Release
22

3-
on: [push]
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
47

58
jobs:
69
build:
7-
runs-on: ubuntu-latest
10+
name: Build on ${{ matrix.os }}
11+
runs-on: ${{ matrix.os }}
12+
strategy:
13+
matrix:
14+
os: [ubuntu-latest, macos-latest, windows-latest]
15+
include:
16+
- os: ubuntu-latest
17+
target: x86_64-unknown-linux-gnu
18+
binary_name: codeinput
19+
archive_name: codeinput-linux.zip
20+
binary_path_suffix: release
21+
- os: macos-latest
22+
target: x86_64-apple-darwin
23+
binary_name: codeinput
24+
archive_name: codeinput-macos.zip
25+
binary_path_suffix: release
26+
- os: windows-latest
27+
target: x86_64-pc-windows-msvc
28+
binary_name: codeinput.exe
29+
archive_name: codeinput-windows.zip
30+
binary_path_suffix: release
831

932
steps:
1033
- name: Checkout Source
11-
id: checkout-source
1234
uses: actions/checkout@v2
35+
1336
- name: Set variables
1437
id: vars
1538
run: |
16-
echo "::set-output name=package_name::$(sed -En 's/name[[:space:]]*=[[:space:]]*"([^"]+)"/\1/p' Cargo.toml | head -1)"
17-
echo "::set-output name=package_version::$(sed -En 's/version[[:space:]]*=[[:space:]]*"([^"]+)"/\1/p' Cargo.toml | head -1)"
18-
- run: |
19-
echo "${{steps.vars.outputs.package_name}}"
20-
echo "${{steps.vars.outputs.package_version}}"
21-
- uses: actions/cache@v4.2.0
39+
echo "package_name=$(sed -En 's/name[[:space:]]*=[[:space:]]*\"([^\"]+)\"/\1/p' Cargo.toml | head -1)" >> $GITHUB_OUTPUT
40+
echo "package_version=$(sed -En 's/version[[:space:]]*=[[:space:]]*\"([^\"]+)\"/\1/p' Cargo.toml | head -1)" >> $GITHUB_OUTPUT
41+
shell: bash
42+
43+
- name: Output variables (for debugging)
44+
run: |
45+
echo "Package Name: ${{ steps.vars.outputs.package_name }}"
46+
echo "Package Version: ${{ steps.vars.outputs.package_version }}"
47+
echo "Target: ${{ matrix.target }}"
48+
echo "Binary Name: ${{ matrix.binary_name }}"
49+
echo "Archive Name: ${{ matrix.archive_name }}"
50+
shell: bash
51+
52+
- name: Cache Cargo dependencies
53+
uses: actions/cache@v4
2254
with:
2355
path: |
2456
~/.cargo/registry
2557
~/.cargo/git
2658
target
27-
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
59+
key: ${{ matrix.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
60+
61+
- name: Install Rust target
62+
run: rustup target add ${{ matrix.target }}
63+
shell: bash
2864

2965
- name: Build
30-
id: build-release
31-
run: cargo build --release
66+
run: cargo build --release --target ${{ matrix.target }}
67+
shell: bash
68+
69+
- name: Prepare archive
70+
shell: bash
71+
run: |
72+
BINARY_PATH="target/${{ matrix.target }}/${{ matrix.binary_path_suffix }}/${{ matrix.binary_name }}"
73+
echo "Binary path is $BINARY_PATH"
74+
if [ ! -f "$BINARY_PATH" ]; then
75+
echo "Binary not found at $BINARY_PATH"
76+
ls -R target
77+
exit 1
78+
fi
79+
if [[ "${{ matrix.os }}" == "ubuntu-latest" || "${{ matrix.os }}" == "macos-latest" ]]; then
80+
chmod +x "$BINARY_PATH"
81+
fi
82+
83+
# Create a staging directory
84+
STAGING_DIR="staging"
85+
mkdir -p "$STAGING_DIR"
86+
87+
# Copy the binary to the staging directory
88+
cp "$BINARY_PATH" "$STAGING_DIR/"
89+
90+
# Zip the contents of the staging directory
91+
cd "$STAGING_DIR"
92+
zip ../${{ matrix.archive_name }} ${{ matrix.binary_name }}
93+
cd ..
94+
echo "Created archive ${{ matrix.archive_name }}"
3295
33-
- name: Zip release
34-
id: zip-release
35-
run: zip -j build.zip target/release/codeinput
3696
37-
- name: Artifact Production
38-
id: create-artifact
97+
- name: Upload build artifact
3998
uses: actions/upload-artifact@v4
4099
with:
41-
name: build
42-
path: build.zip
100+
name: build-${{ matrix.os }} # e.g., build-ubuntu-latest
101+
path: ${{ matrix.archive_name }}
102+
103+
release:
104+
name: Create GitHub Release
105+
runs-on: ubuntu-latest
106+
needs: build # Ensures this job runs after all build jobs in the matrix are complete
107+
permissions:
108+
contents: write # Required to create releases and upload assets
109+
actions: read # Required to download artifacts
110+
111+
steps:
112+
- name: Checkout Source (for version info)
113+
uses: actions/checkout@v2
114+
115+
- name: Set version variables from tag
116+
id: tag_vars
117+
run: |
118+
TAG_NAME="${{ github.ref_name }}"
119+
# Assuming tag is vA.B.C, package_version becomes A.B.C
120+
PACKAGE_VERSION="${TAG_NAME#v}"
121+
echo "package_version=${PACKAGE_VERSION}" >> $GITHUB_OUTPUT
122+
# We can try to get package_name from Cargo.toml if needed, or define it statically
123+
# For simplicity, let's try Cargo.toml first
124+
PACKAGE_NAME=$(sed -En 's/name[[:space:]]*=[[:space:]]*"([^"]+)"/\1/p' Cargo.toml | head -1)
125+
echo "package_name=${PACKAGE_NAME}" >> $GITHUB_OUTPUT
126+
shell: bash
127+
128+
- name: Output version variables (for debugging)
129+
run: |
130+
echo "Package Name: ${{ steps.tag_vars.outputs.package_name }}"
131+
echo "Package Version: ${{ steps.tag_vars.outputs.package_version }}"
132+
shell: bash
133+
134+
- name: Download all build artifacts
135+
uses: actions/download-artifact@v4
136+
with:
137+
path: release-artifacts # Artifacts will be in release-artifacts/build-ubuntu-latest/*, release-artifacts/build-macos-latest/* etc.
138+
139+
- name: List downloaded artifacts (for debugging)
140+
run: ls -R release-artifacts
141+
shell: bash
43142

44-
- name: Remove Same Release
143+
- name: Remove Same Release (if exists)
45144
uses: omarabid-forks/action-rollback@stable
46-
continue-on-error: true
145+
continue-on-error: true # Important if the release doesn't exist yet
47146
with:
48-
tag: ${{ steps.vars.outputs.package_version }}
147+
tag: ${{ github.ref_name }} # Use the tag that triggered the workflow
49148
env:
50149
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51150

52151
- name: Create Release
53-
id: create-release
152+
id: create_release
54153
uses: actions/create-release@latest
55154
env:
56-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
155+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
57156
with:
58-
tag_name: ${{steps.vars.outputs.package_version}}
59-
release_name: Version ${{steps.vars.outputs.package_version}}
60-
body: ${{steps.vars.outputs.package_name}} - ${{steps.vars.outputs.package_version}}
157+
tag_name: ${{ github.ref_name }}
158+
release_name: Version ${{ steps.tag_vars.outputs.package_version }}
159+
body: |
160+
Release of version ${{ steps.tag_vars.outputs.package_version }} for ${{ steps.tag_vars.outputs.package_name }}.
161+
Includes builds for Windows, macOS (x86_64), and Linux (x86_64).
61162
draft: false
62163
prerelease: false
63164

64-
- name: Upload Artifact
65-
id: upload-release-asset
66-
uses: actions/upload-release-asset@v1
165+
- name: Upload Release Assets
166+
shell: bash
67167
env:
68168
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
69-
with:
70-
upload_url: ${{ steps.create-release.outputs.upload_url }}
71-
asset_path: build.zip
72-
asset_name: build.zip
73-
asset_content_type: application/zip
169+
UPLOAD_URL: ${{ steps.create_release.outputs.upload_url }}
170+
run: |
171+
echo "Listing files to upload:"
172+
find release-artifacts -type f -print0 | while IFS= read -r -d $'\0' file; do
173+
ARCHIVE_NAME=$(basename "$file")
174+
echo "Uploading $file as $ARCHIVE_NAME"
175+
gh release upload "${{ github.ref_name }}" "$file" --clobber
176+
done
177+
echo "Finished uploading assets."
74178
75-
- uses: omarabid-forks/purge-artifacts@v1
179+
- name: Purge All Artifacts (optional, cleans up build artifacts after release)
180+
if: always() # Run this step even if previous steps fail
181+
uses: omarabid-forks/purge-artifacts@v1
76182
with:
77183
token: ${{ secrets.GITHUB_TOKEN }}
78-
expire-in: 0
184+
expire-in: 0 # Immediately purge
185+
# Optional: specify by name if you only want to purge the 'build-*' artifacts
186+
# name: build-*
187+
```

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
runs-on: ${{ matrix.os }}
99
strategy:
1010
matrix:
11-
os: [ubuntu-latest]
11+
os: [ubuntu-latest, macos-latest, windows-latest]
1212
steps:
1313
- name: Checkout sources
1414
uses: actions/checkout@v2

0 commit comments

Comments
 (0)