Repository navigation
163 lines (148 loc) · 6.23 KB
/
Copy pathrelease.yml
File metadata and controls
163 lines (148 loc) · 6.23 KB
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
155
156
157
158
159
160
161
162
163
name: release
# Tag a release with `git tag v0.1.1 && git push --tags`. This workflow
# builds the c0mpute binary for Linux / macOS / Windows on x86_64 and
# aarch64, packages each as a tarball (zip on Windows), generates a
# SHA-256 checksum, and uploads the lot to a GitHub Release.
#
# The release is created as a DRAFT first, every platform uploads into the
# draft, and only when all five uploads succeeded does the `publish` job make
# it public and mark it Latest. Before this, softprops/action-gh-release
# published + marked Latest on the first upload, so for ~3 minutes after a
# tag `releases/latest/download/<artifact>` 404'd for every platform still
# building, and `curl -fsSL https://c0mpute.com/install.sh | sh` failed.
# A failed platform leaves the draft unpublished (Latest stays on the
# previous release); fix and re-run the failed jobs.
#
# Stable install URL: https://c0mpute.com/releases/latest/<artifact>
# redirects to https://github.com/profullstack/c0mpute/releases/latest/download/<artifact>
# (configured in apps/web/next.config.mjs).
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag:
description: "Existing tag to (re)build and publish, e.g. v0.2.33"
required: true
permissions:
contents: write
env:
TAG: ${{ inputs.tag || github.ref_name }}
GH_REPO: ${{ github.repository }}
jobs:
draft:
name: create draft release
runs-on: ubuntu-latest
steps:
- name: Create the release as a draft (or reuse it)
env:
GH_TOKEN: ${{ github.token }}
run: |
set -eu
case "$TAG" in v*) ;; *) echo "not a release tag: $TAG" >&2; exit 1 ;; esac
if gh release view "$TAG" --json isDraft >/dev/null 2>&1; then
echo "release $TAG exists (draft=$(gh release view "$TAG" --json isDraft -q .isDraft)); uploads will replace its assets"
else
gh release create "$TAG" --draft --verify-tag --generate-notes --title "$TAG"
fi
release:
name: ${{ matrix.platform }}
needs: draft
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# Linux: musl targets produce fully static binaries that run
# on any Linux distro (no glibc version dependency). Building
# against glibc on ubuntu-latest (24.04, glibc 2.39) made the
# v0.1.0 binary unusable on older Linux.
- platform: linux-x86_64
os: ubuntu-latest
target: x86_64-unknown-linux-musl
- platform: linux-aarch64
os: ubuntu-24.04-arm
target: aarch64-unknown-linux-musl
# Both Mac targets cross-built from the arm64 runner — Intel
# mac runners (macos-13) have minimal capacity and queue
# indefinitely. Apple's Xcode toolchain cross-compiles
# x86_64-apple-darwin natively from arm64.
- platform: darwin-x86_64
os: macos-latest
target: x86_64-apple-darwin
- platform: darwin-aarch64
os: macos-latest
target: aarch64-apple-darwin
- platform: windows-x86_64
os: windows-latest
target: x86_64-pc-windows-msvc
steps:
- uses: actions/checkout@v5
with:
ref: ${{ env.TAG }}
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Cache cargo
uses: Swatinem/rust-cache@v2
with:
shared-key: ${{ matrix.target }}
- name: Install musl tools (Linux musl targets)
if: contains(matrix.target, 'linux-musl')
run: sudo apt-get update && sudo apt-get install -y musl-tools
- name: Build c0mpute binary
run: cargo build --release --bin c0mpute --target ${{ matrix.target }}
- name: Package artifact (Unix)
if: runner.os != 'Windows'
shell: bash
run: |
set -eu
BIN=target/${{ matrix.target }}/release/c0mpute
ARTIFACT=c0mpute-${{ matrix.platform }}.tar.gz
tar -czf "$ARTIFACT" -C "$(dirname "$BIN")" c0mpute
shasum -a 256 "$ARTIFACT" > "$ARTIFACT.sha256"
echo "ARTIFACT=$ARTIFACT" >> "$GITHUB_ENV"
echo "ARTIFACT_SHA=$ARTIFACT.sha256" >> "$GITHUB_ENV"
- name: Package artifact (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$bin = "target/${{ matrix.target }}/release/c0mpute.exe"
$artifact = "c0mpute-${{ matrix.platform }}.zip"
Compress-Archive -Path $bin -DestinationPath $artifact
$hash = (Get-FileHash -Algorithm SHA256 $artifact).Hash.ToLower()
"$hash $artifact" | Out-File -Encoding ascii "$artifact.sha256"
"ARTIFACT=$artifact" | Out-File -Append -Encoding ascii $env:GITHUB_ENV
"ARTIFACT_SHA=$artifact.sha256" | Out-File -Append -Encoding ascii $env:GITHUB_ENV
- name: Upload to the draft release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: gh release upload "$TAG" "$ARTIFACT" "$ARTIFACT_SHA" --clobber
publish:
name: publish + mark latest
# Runs only when every platform job succeeded (needs + default success()).
needs: release
runs-on: ubuntu-latest
steps:
- name: Check every asset is on the release, then publish it as Latest
env:
GH_TOKEN: ${{ github.token }}
run: |
set -eu
want="c0mpute-linux-x86_64.tar.gz c0mpute-linux-aarch64.tar.gz c0mpute-darwin-x86_64.tar.gz c0mpute-darwin-aarch64.tar.gz c0mpute-windows-x86_64.zip"
have=$(gh release view "$TAG" --json assets -q '.assets[].name')
for a in $want; do
for f in "$a" "$a.sha256"; do
echo "$have" | grep -qx "$f" || { echo "missing asset $f on $TAG; not publishing" >&2; exit 1; }
done
done
gh release edit "$TAG" --draft=false --latest
# The public download URL must now serve every platform.
for a in $want; do
code=$(curl -s -o /dev/null -w '%{http_code}' -L "https://github.com/$GH_REPO/releases/download/$TAG/$a")
echo "$a -> $code"
[ "$code" = "200" ] || { echo "asset $a not downloadable after publish" >&2; exit 1; }
done