1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
name: Release binaries
# Fires whenever a GitHub Release is published. release-plz creates the
# release on its own (see release-plz.yml); this workflow attaches the
# cross-built binaries to it.
#
# Also exposed via workflow_dispatch so a failed asset upload can be
# retried against an existing release without re-tagging.
on:
release:
types:
workflow_dispatch:
inputs:
tag:
description: "Release tag to upload to (e.g. v0.0.3)"
required: true
type: string
permissions:
# gh release upload needs to attach assets.
contents: write
env:
CARGO_TERM_COLOR: always
# Resolve the target tag once — `release` and `workflow_dispatch` use
# different paths in the event payload.
TAG: ${{ github.event.release.tag_name || inputs.tag }}
jobs:
build:
name: build ${{ matrix.target }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
archive: tar.gz
asset_suffix: linux-x86_64
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
archive: tar.gz
asset_suffix: linux-aarch64
apt_packages: gcc-aarch64-linux-gnu
linker: aarch64-linux-gnu-gcc
- target: x86_64-pc-windows-msvc
os: windows-latest
archive: zip
asset_suffix: windows-x86_64
- target: aarch64-pc-windows-msvc
os: windows-latest
archive: zip
asset_suffix: windows-aarch64
steps:
- uses: actions/checkout@v6
- name: Install cross compiler (Linux aarch64)
if: matrix.apt_packages
run: |
sudo apt-get update
sudo apt-get install -y ${{ matrix.apt_packages }}
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}
- name: Build
shell: bash
env:
# Only set the linker env var when the matrix entry asks for one.
# GitHub Actions silently drops empty `env:` values, so this is
# a no-op for the native targets.
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: ${{ matrix.linker }}
run: cargo build --release --bin fstool --target ${{ matrix.target }}
- name: Stage archive contents
shell: bash
run: |
mkdir staging
if [[ "${{ runner.os }}" == "Windows" ]]; then
cp "target/${{ matrix.target }}/release/fstool.exe" staging/
else
cp "target/${{ matrix.target }}/release/fstool" staging/
fi
cp README.md LICENSE staging/
- name: Pack archive
id: pack
shell: bash
run: |
name="fstool-${TAG}-${{ matrix.asset_suffix }}"
if [[ "${{ matrix.archive }}" == "zip" ]]; then
asset="${name}.zip"
(cd staging && 7z a "../${asset}" *)
else
asset="${name}.tar.gz"
tar -C staging -czf "${asset}" .
fi
echo "asset=${asset}" >> "$GITHUB_OUTPUT"
- name: Upload to release
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release upload "${TAG}" "${{ steps.pack.outputs.asset }}" --clobber
build-macos-universal:
name: build macos universal
runs-on: macos-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-apple-darwin,aarch64-apple-darwin
- uses: Swatinem/rust-cache@v2
with:
key: macos-universal
- name: Build both Apple slices
run: |
cargo build --release --bin fstool --target x86_64-apple-darwin
cargo build --release --bin fstool --target aarch64-apple-darwin
- name: Lipo into a universal binary
run: |
mkdir staging
lipo -create -output staging/fstool \
target/x86_64-apple-darwin/release/fstool \
target/aarch64-apple-darwin/release/fstool
file staging/fstool
cp README.md LICENSE staging/
- name: Pack archive
id: pack
run: |
asset="fstool-${TAG}-macos-universal.tar.gz"
tar -C staging -czf "${asset}" .
echo "asset=${asset}" >> "$GITHUB_OUTPUT"
- name: Upload to release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release upload "${TAG}" "${{ steps.pack.outputs.asset }}" --clobber