Skip to content

Commit 99cdd58

Browse files
committed
feat: linux musl static bins / windows aarch64
- create linux executables linked statically to musl - drop gnu (glibc) target, executable will work on alpine & glibc based distros (debian etc) - create windows aarch64 target - refactor release script & workflow to match pact-reference - builds on pull request to master/main branch, in debug mode Related epics - musl all the things - pact-foundation/roadmap#30
1 parent 40abddf commit 99cdd58

File tree

5 files changed

+192
-60
lines changed

5 files changed

+192
-60
lines changed

.github/workflows/release.yml

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ on:
44
release:
55
types: [published]
66

7+
pull_request:
8+
branches:
9+
- main
10+
711
concurrency:
812
group: ci-${{ github.ref }}
913
cancel-in-progress: false
@@ -13,32 +17,59 @@ jobs:
1317
runs-on: ${{ matrix.operating-system }}
1418
strategy:
1519
matrix:
16-
operating-system: [ubuntu-20.04, windows-2019, macos-12]
17-
env:
18-
pact_do_not_track: true
20+
include:
21+
- operating-system: ubuntu-20.04
22+
targets: x86_64-unknown-linux-gnu,x86_64-unknown-linux-musl,aarch64-unknown-linux-gnu,aarch64-unknown-linux-musl
23+
- operating-system: windows-2019
24+
targets: aarch64-pc-windows-msvc,x86_64-pc-windows-msvc
25+
- operating-system: macos-12
26+
targets: aarch64-apple-darwin,x86_64-apple-darwin
27+
fail-fast: false
1928
steps:
20-
- uses: actions/checkout@v2
29+
- uses: actions/checkout@v4
2130
- name: Install stable Rust toolchain
22-
uses: actions-rs/toolchain@v1
31+
uses: dtolnay/rust-toolchain@stable
2332
with:
24-
profile: minimal
2533
toolchain: stable
26-
override: true
27-
target: aarch64-apple-darwin
34+
targets: ${{ matrix.targets }}
35+
36+
- name: Rust caching
37+
uses: Swatinem/rust-cache@v2
38+
with:
39+
workspaces: rust
40+
41+
- name: Set up QEMU
42+
if: runner.os == 'Linux'
43+
uses: docker/setup-qemu-action@v3
44+
45+
- name: Set up Docker Buildx
46+
if: runner.os == 'Linux'
47+
uses: docker/setup-buildx-action@v3
48+
- name: Cargo flags
49+
id: cargo-flags
50+
shell: bash
51+
run: |
52+
if [[ "${{ github.event_name }}" = "release" ]]; then
53+
echo "flags=--release" >> "$GITHUB_OUTPUT"
54+
else
55+
echo "flags=" >> "$GITHUB_OUTPUT"
56+
fi
2857
- name: Install Protoc
2958
uses: arduino/setup-protoc@v1
3059
with:
3160
repo-token: ${{ secrets.GITHUB_TOKEN }}
3261
- name: Install LLVM
3362
run: choco install -y llvm
3463
if: runner.os == 'Windows'
35-
- run: ./release.sh ${{ runner.os }} ${{ github.ref }}
64+
- run: ./release.sh ${{ runner.os }} ${{ github.ref }} ${{ steps.cargo-flags.outputs.flags }}
3665
shell: bash
3766
- name: Upload Release Assets
67+
if: |
68+
startsWith(github.ref, 'refs/tags/v')
3869
id: upload-release-asset
3970
uses: svenstaro/upload-release-action@v2
4071
with:
4172
repo_token: ${{ secrets.GITHUB_TOKEN }}
42-
file: target/artifacts/*
73+
file: release_artifacts/*
4374
file_glob: true
44-
tag: ${{ github.ref }}
75+
tag: ${{ github.ref }}

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# will have compiled files and executables
22
target/
3-
3+
# Generated Release Artifacts
4+
release_artifacts
45
# These are backup files generated by rustfmt
56
**/*.rs.bk
67

Cross.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
[target.aarch64-unknown-linux-gnu]
1+
[target.x86_64-unknown-linux-musl]
22
pre-build=[
3-
"dpkg --add-architecture arm64 && apt-get update && apt-get install --assume-yes wget unzip",
3+
"apt-get update && apt-get install --assume-yes wget unzip",
44
"wget https://github.com/protocolbuffers/protobuf/releases/download/v21.5/protoc-21.5-linux-x86_64.zip",
55
"unzip protoc-21.5-linux-x86_64.zip -d /usr/local/"
66
]
7+
[target.aarch64-unknown-linux-musl]
8+
pre-build=[
9+
"dpkg --add-architecture arm64 && apt-get update && apt-get install --assume-yes wget unzip",
10+
"wget https://github.com/protocolbuffers/protobuf/releases/download/v21.5/protoc-21.5-linux-x86_64.zip",
11+
"unzip protoc-21.5-linux-x86_64.zip -d /usr/local/"
12+
]

release.sh

Lines changed: 122 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,137 @@
11
#!/bin/bash
22

3-
if [ $# -lt 1 ]
3+
set -e
4+
set -x
5+
6+
RUST_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd )"
7+
8+
source "$RUST_DIR/scripts/gzip-and-sum.sh"
9+
ARTIFACTS_DIR=${ARTIFACTS_DIR:-"$RUST_DIR/release_artifacts"}
10+
mkdir -p "$ARTIFACTS_DIR"
11+
export CARGO_TARGET_DIR=${CARO_TARGET_DIR:-"$RUST_DIR/target"}
12+
13+
if [ $# -lt 2 ]
414
then
5-
echo "Usage : $0 <Linux|Windows|macOS> <version tag>"
15+
echo "Usage : $0 <Linux|Windows|macOS> <release version> <cargo flags>"
616
exit
717
fi
818

9-
set -e
19+
APP=pact-protobuf-plugin
20+
OS=$1
21+
shift;
22+
VERSION=$1
23+
shift;
24+
echo Building Release for "$OS"
25+
# All flags passed to this script are passed to cargo.
26+
cargo_flags=( "$@" )
27+
build_manifest() {
28+
NEXT=$(echo "$VERSION" | sed 's/^refs\/tags\/v-//')
29+
# get latest release tag, if NEXT still contains refs
30+
if [[ "${NEXT}" =~ "refs"* ]]; then
31+
CRATE_VERSION=$(cat Cargo.toml| grep 'version = ".*"' -m1 | cut -d '"' -f 2)
32+
echo "defaulting NEXT=$VERSION to version from Cargo.toml $CRATE_VERSION"
33+
NEXT=$CRATE_VERSION
34+
# LATEST_RELEASE=$(echo $(curl -s https://api.github.com/repos/pact-foundation/pact-stub-server/releases/latest | jq -r '.name') | sed 's/v//')
35+
# echo "defaulting NEXT=$VERSION to latest release $LATEST_RELEASE"
36+
# NEXT=$LATEST_RELEASE
37+
fi
38+
sed -e 's/\"version\": \".*\"/\"version\": \"'${NEXT}'\"/' "$RUST_DIR/pact-plugin.json" > "$ARTIFACTS_DIR/pact-plugin.json"
39+
sed -e 's/VERSION=\".*\"/VERSION=\"'${NEXT}'\"/' "$RUST_DIR/scripts/install-plugin.sh" > "$ARTIFACTS_DIR/install-plugin.sh"
40+
openssl dgst -sha256 -r $ARTIFACTS_DIR/install-plugin.sh > "$ARTIFACTS_DIR/install-plugin.sh.sha256"
41+
}
42+
install_cross() {
43+
cargo install cross@0.2.5
44+
}
45+
46+
build_linux_x86_64() {
47+
install_cross
48+
cargo clean
49+
cross build --target=x86_64-unknown-linux-musl "${cargo_flags[@]}"
50+
if [[ "${cargo_flags[*]}" =~ "--release" ]]; then
51+
gzip_and_sum \
52+
"$CARGO_TARGET_DIR/x86_64-unknown-linux-musl/release/${APP}" \
53+
"$ARTIFACTS_DIR/${APP}-linux-x86_64.gz"
54+
# cargo clean
55+
fi
56+
}
57+
58+
build_linux_aarch64() {
59+
install_cross
60+
cargo clean
61+
cross build --target=aarch64-unknown-linux-musl "${cargo_flags[@]}"
62+
63+
if [[ "${cargo_flags[*]}" =~ "--release" ]]; then
64+
gzip_and_sum \
65+
"$CARGO_TARGET_DIR/aarch64-unknown-linux-musl/release/${APP}" \
66+
"$ARTIFACTS_DIR/${APP}-linux-aarch64.gz"
67+
fi
68+
}
69+
# Build the x86_64 darwin release
70+
build_macos_x86_64() {
71+
cargo build --target x86_64-apple-darwin "${cargo_flags[@]}"
72+
73+
if [[ "${cargo_flags[*]}" =~ "--release" ]]; then
74+
gzip_and_sum \
75+
"$CARGO_TARGET_DIR/x86_64-apple-darwin/release/${APP}" \
76+
"$ARTIFACTS_DIR/${APP}-osx-x86_64.gz"
77+
gzip_and_sum \
78+
"$CARGO_TARGET_DIR/x86_64-apple-darwin/release/${APP}" \
79+
"$ARTIFACTS_DIR/${APP}-macos-x86_64.gz"
80+
fi
81+
}
82+
83+
# Build the aarch64 darwin release
84+
build_macos_aarch64() {
85+
cargo build --target aarch64-apple-darwin "${cargo_flags[@]}"
86+
87+
if [[ "${cargo_flags[*]}" =~ "--release" ]]; then
88+
gzip_and_sum \
89+
"$CARGO_TARGET_DIR/aarch64-apple-darwin/release/${APP}" \
90+
"$ARTIFACTS_DIR/${APP}-osx-aarch64.gz"
91+
gzip_and_sum \
92+
"$CARGO_TARGET_DIR/aarch64-apple-darwin/release/${APP}" \
93+
"$ARTIFACTS_DIR/${APP}-macos-aarch64.gz"
94+
fi
95+
}
96+
97+
# Build the x86_64 windows release
98+
build_windows_x86_64() {
99+
cargo build --target x86_64-pc-windows-msvc "${cargo_flags[@]}"
100+
101+
# If --release in cargo flags, then gzip and sum the release artifacts
102+
if [[ "${cargo_flags[*]}" =~ "--release" ]]; then
103+
gzip_and_sum \
104+
"$CARGO_TARGET_DIR/x86_64-pc-windows-msvc/release/${APP}.exe" \
105+
"$ARTIFACTS_DIR/${APP}-windows-x86_64.exe.gz"
106+
fi
107+
}
10108

11-
echo Building Release for "$1" - "$2"
109+
# Build the aarch64 windows release
110+
build_windows_aarch64() {
111+
cargo build --target aarch64-pc-windows-msvc "${cargo_flags[@]}"
12112

13-
cargo clean
14-
mkdir -p target/artifacts
113+
if [[ "${cargo_flags[*]}" =~ "--release" ]]; then
114+
gzip_and_sum \
115+
"$CARGO_TARGET_DIR/aarch64-pc-windows-msvc/release/${APP}.exe" \
116+
"$ARTIFACTS_DIR/${APP}-windows-aarch64.exe.gz"
117+
fi
118+
}
15119

16-
case "$1" in
120+
case "$OS" in
17121
Linux) echo "Building for Linux"
18-
docker run --rm --user "$(id -u)":"$(id -g)" -v "$(pwd):/workspace" -w /workspace -t \
19-
pactfoundation/rust-musl-build -c 'LIBZ_SYS_STATIC=1 cargo build --release'
20-
gzip -c target/release/pact-protobuf-plugin > target/artifacts/pact-protobuf-plugin-linux-x86_64.gz
21-
openssl dgst -sha256 -r target/artifacts/pact-protobuf-plugin-linux-x86_64.gz > target/artifacts/pact-protobuf-plugin-linux-x86_64.gz.sha256
22-
cp pact-plugin.json target/artifacts
23-
NEXT=$(echo "$2" | cut -d\- -f2)
24-
sed -e 's/VERSION=\"0.1.5\"/VERSION=\"'${NEXT}'\"/' scripts/install-plugin.sh > target/artifacts/install-plugin.sh
25-
openssl dgst -sha256 -r target/artifacts/install-plugin.sh > target/artifacts/install-plugin.sh.sha256
26-
27-
# Build aarch64
28-
cargo install cross --git https://github.com/cross-rs/cross
29-
cross build --target aarch64-unknown-linux-gnu --release
30-
gzip -c target/aarch64-unknown-linux-gnu/release/pact-protobuf-plugin > target/artifacts/pact-protobuf-plugin-linux-aarch64.gz
31-
openssl dgst -sha256 -r target/artifacts/pact-protobuf-plugin-linux-aarch64.gz > target/artifacts/pact-protobuf-plugin-linux-aarch64.gz.sha256
122+
build_linux_x86_64
123+
build_linux_aarch64
124+
build_manifest
32125
;;
33-
Windows) echo "Building for Windows"
34-
cargo build --release
35-
gzip -c target/release/pact-protobuf-plugin.exe > target/artifacts/pact-protobuf-plugin-windows-x86_64.exe.gz
36-
openssl dgst -sha256 -r target/artifacts/pact-protobuf-plugin-windows-x86_64.exe.gz > target/artifacts/pact-protobuf-plugin-windows-x86_64.exe.gz.sha256
126+
Windows) echo "Building for windows"
127+
build_windows_x86_64
128+
build_windows_aarch64
37129
;;
38-
macOS) echo "Building for OSX"
39-
cargo build --release
40-
gzip -c target/release/pact-protobuf-plugin > target/artifacts/pact-protobuf-plugin-osx-x86_64.gz
41-
openssl dgst -sha256 -r target/artifacts/pact-protobuf-plugin-osx-x86_64.gz > target/artifacts/pact-protobuf-plugin-osx-x86_64.gz.sha256
42-
# macos
43-
gzip -c target/release/pact-protobuf-plugin > target/artifacts/pact-protobuf-plugin-macos-x86_64.gz
44-
openssl dgst -sha256 -r target/artifacts/pact-protobuf-plugin-macos-x86_64.gz > target/artifacts/pact-protobuf-plugin-macos-x86_64.gz.sha256
45-
46-
# M1
47-
# export SDKROOT=$(xcrun -sdk macosx11.1 --show-sdk-path)
48-
# export MACOSX_DEPLOYMENT_TARGET=$(xcrun -sdk macosx11.1 --show-sdk-platform-version)
49-
export MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-12}
50-
cargo build --target aarch64-apple-darwin --release
51-
52-
gzip -c target/aarch64-apple-darwin/release/pact-protobuf-plugin > target/artifacts/pact-protobuf-plugin-osx-aarch64.gz
53-
openssl dgst -sha256 -r target/artifacts/pact-protobuf-plugin-osx-aarch64.gz > target/artifacts/pact-protobuf-plugin-osx-aarch64.gz.sha256
54-
# macos
55-
gzip -c target/aarch64-apple-darwin/release/pact-protobuf-plugin > target/artifacts/pact-protobuf-plugin-macos-aarch64.gz
56-
openssl dgst -sha256 -r target/artifacts/pact-protobuf-plugin-macos-aarch64.gz > target/artifacts/pact-protobuf-plugin-macos-aarch64.gz.sha256
130+
macOS) echo "Building for macos"
131+
build_macos_x86_64
132+
build_macos_aarch64
57133
;;
58-
*) echo "$1 is not a recognised OS"
134+
*) echo "$OS is not a recognised OS"
59135
exit 1
60136
;;
61-
esac
137+
esac

scripts/gzip-and-sum.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
# Gzip and sum a file.
4+
#
5+
# Usage: gzip_and_sum <orig_file> <target_file> [<digest_file>]
6+
#
7+
# - orig_file: the file to gzip and sum
8+
# - target_file: the file to write the gzipped file to
9+
# - digest_file: the file to write the digest to. If not provided, defaults to
10+
# <target_file>.sha256
11+
gzip_and_sum() {
12+
orig_file=$1
13+
target_file=$2
14+
digest_file=${3:-$target_file.sha256}
15+
16+
gzip --stdout --best "$orig_file" > "$target_file"
17+
openssl dgst -sha256 -r "$target_file" > "$digest_file"
18+
}

0 commit comments

Comments
 (0)