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
name: release
# Build prebuilt sopsy binaries and attach them to the GitHub Release for a tag,
# so users can install via Homebrew (kigster/tap) without a Rust toolchain.
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag:
description: "Existing tag to build and attach binaries to (e.g. v1.0.2)"
required: true
permissions:
contents: write
jobs:
# Pushing a tag does not create a GitHub Release object, and
# upload-rust-binary-action attaches to an existing release rather than
# creating one — so create (or reuse) the release first, once.
create-release:
runs-on: ubuntu-latest
steps:
- name: Ensure the GitHub release exists
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
TAG: ${{ github.event.inputs.tag || github.ref_name }}
run: |
set -euo pipefail
if gh release view "$TAG" >/dev/null 2>&1; then
echo "Release $TAG already exists; reusing it."
else
gh release create "$TAG" --title "$TAG" --generate-notes
fi
upload:
name: ${{ matrix.target }}
needs: create-release
strategy:
fail-fast: false
matrix:
include:
- target: aarch64-apple-darwin
os: macos-14
# Cross-compiled on the Apple Silicon runner: GitHub is sunsetting the
# Intel macos-13 runners (they can queue indefinitely), and macos-14
# builds the x86_64 target reliably via rustup.
- target: x86_64-apple-darwin
os: macos-14
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
- target: aarch64-unknown-linux-gnu
os: ubuntu-24.04-arm
runs-on: ${{ matrix.os }}
steps:
# v7 runs on the node24 runtime (node20 is deprecated on GitHub runners
# and removed in fall 2026).
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ github.event.inputs.tag || github.ref }}
# Builds (cross-compiling where needed), tars the binary as
# sopsy-<target>.tar.gz, generates a .sha256, and uploads to the release.
# Pinned to a full commit SHA (supply-chain hardening); bump deliberately.
# Composite action (shell steps, no Node runtime) — unaffected by the
# node20 deprecation; this SHA is v1.30.2, the latest release.
- uses: taiki-e/upload-rust-binary-action@f0d45ae91ee7b8ee928de7a9d04d893a08bcbec6 # v1.30.2
with:
bin: sopsy
target: ${{ matrix.target }}
archive: sopsy-$target
checksum: sha256
ref: refs/tags/${{ github.event.inputs.tag || github.ref_name }}
token: ${{ secrets.GITHUB_TOKEN }}
notify-tap:
name: refresh Homebrew formula
needs: upload
runs-on: ubuntu-latest
steps:
- name: Trigger tap update-formula workflow
env:
TAG: ${{ github.event.inputs.tag || github.ref_name }}
# Optional: a PAT with `repo` scope on kigster/homebrew-tap. Without it
# the tap is updated by running its update-formula workflow manually.
GH_TOKEN: ${{ secrets.TAP_DISPATCH_TOKEN }}
run: |
set -euo pipefail
if [ -z "${GH_TOKEN:-}" ]; then
echo "TAP_DISPATCH_TOKEN not set — skipping auto-update."
echo "Run the tap's update-formula workflow manually:"
echo " gh workflow run update-formula.yml -R kigster/homebrew-tap -f tag=$TAG"
exit 0
fi
gh api "repos/kigster/homebrew-tap/dispatches" \
-f "event_type=sopsy-release" \
-f "client_payload[tag]=$TAG"