Skip to content

Commit ab3484a

Browse files
committed
added release pipeline
1 parent 7ea69d0 commit ab3484a

1 file changed

Lines changed: 180 additions & 0 deletions

File tree

.github/workflows/release.yml

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Automatically builds standalone binaries for all platforms and creates a
2+
# GitHub pre-release whenever source code changes are pushed to master.
3+
#
4+
# Triggered only by changes inside:
5+
# src/ | global.json | Directory.Build.props | *.sln
6+
#
7+
# Each run produces a release tagged build-YYYYMMDD-<sha7> with four
8+
# self-contained single-file executables attached as assets:
9+
# todo-win-x64.exe | todo-linux-x64 | todo-osx-x64 | todo-osx-arm64
10+
#
11+
# Windows binary is Authenticode-signed when the two repository secrets are set:
12+
# Base64_Encoded_Pfx – base64-encoded .pfx certificate
13+
# Pfx_Key – .pfx password
14+
15+
name: Release Binaries
16+
17+
on:
18+
push:
19+
branches: [ "master" ]
20+
paths:
21+
- 'src/**'
22+
- 'tests/**'
23+
- '**.csproj'
24+
- '*.sln'
25+
- 'global.json'
26+
- 'Directory.Build.props'
27+
28+
permissions:
29+
contents: write # required to create GitHub releases
30+
31+
env:
32+
PROJECT: src/CliTodoSharp/CliTodoSharp.csproj
33+
34+
jobs:
35+
# ── Build one self-contained binary per platform ──────────────────────────
36+
build:
37+
name: Build ${{ matrix.rid }}
38+
runs-on: ${{ matrix.os }}
39+
40+
strategy:
41+
fail-fast: false
42+
matrix:
43+
include:
44+
- rid: win-x64
45+
os: windows-latest
46+
bin: todo.exe
47+
asset: todo-win-x64.exe
48+
sign: true
49+
- rid: linux-x64
50+
os: ubuntu-latest
51+
bin: todo
52+
asset: todo-linux-x64
53+
sign: false
54+
- rid: osx-x64
55+
os: macos-latest
56+
bin: todo
57+
asset: todo-osx-x64
58+
sign: false
59+
- rid: osx-arm64
60+
os: macos-latest
61+
bin: todo
62+
asset: todo-osx-arm64
63+
sign: false
64+
65+
env:
66+
HAS_SIGNING_CERT: ${{ secrets.Base64_Encoded_Pfx != '' }}
67+
OUT: publish/${{ matrix.rid }}
68+
69+
steps:
70+
- name: Checkout
71+
uses: actions/checkout@v4
72+
73+
- name: Setup .NET
74+
uses: actions/setup-dotnet@v4
75+
with:
76+
dotnet-version: '10.0.x'
77+
78+
- name: Publish ${{ matrix.rid }}
79+
run: |
80+
dotnet publish ${{ env.PROJECT }} \
81+
-c Release \
82+
-r ${{ matrix.rid }} \
83+
--self-contained true \
84+
-p:PublishSingleFile=true \
85+
-p:IncludeNativeLibrariesForSelfExtract=true \
86+
-o ${{ env.OUT }}
87+
shell: bash
88+
89+
# ── Windows code signing ─────────────────────────────────────────────
90+
- name: Decode signing certificate
91+
if: matrix.sign == true && env.HAS_SIGNING_CERT == 'true'
92+
env:
93+
PFX_B64: ${{ secrets.Base64_Encoded_Pfx }}
94+
run: |
95+
$bytes = [System.Convert]::FromBase64String($env:PFX_B64)
96+
[IO.File]::WriteAllBytes("$env:RUNNER_TEMP\signing.pfx", $bytes)
97+
shell: pwsh
98+
99+
- name: Sign executable
100+
if: matrix.sign == true && env.HAS_SIGNING_CERT == 'true'
101+
env:
102+
PFX_KEY: ${{ secrets.Pfx_Key }}
103+
run: |
104+
$signtool = Get-ChildItem `
105+
'C:\Program Files (x86)\Windows Kits\10\bin' `
106+
-Recurse -Filter signtool.exe |
107+
Sort-Object FullName -Descending |
108+
Select-Object -First 1 -ExpandProperty FullName
109+
110+
& $signtool sign `
111+
/fd sha256 `
112+
/td sha256 `
113+
/tr http://timestamp.digicert.com `
114+
/f "$env:RUNNER_TEMP\signing.pfx" `
115+
/p "$env:PFX_KEY" `
116+
/v "${{ env.OUT }}\${{ matrix.bin }}"
117+
shell: pwsh
118+
119+
- name: Remove signing certificate
120+
if: matrix.sign == true && env.HAS_SIGNING_CERT == 'true'
121+
run: Remove-Item -Path "$env:RUNNER_TEMP\signing.pfx" -Force
122+
shell: pwsh
123+
124+
# ── Rename to asset name and upload ──────────────────────────────────
125+
- name: Rename binary
126+
run: |
127+
cp ${{ env.OUT }}/${{ matrix.bin }} ${{ env.OUT }}/${{ matrix.asset }}
128+
shell: bash
129+
130+
- name: Upload artifact
131+
uses: actions/upload-artifact@v4
132+
with:
133+
name: ${{ matrix.asset }}
134+
path: ${{ env.OUT }}/${{ matrix.asset }}
135+
if-no-files-found: error
136+
137+
# ── Create GitHub release with all four binaries ──────────────────────────
138+
release:
139+
name: Create Release
140+
needs: build
141+
runs-on: ubuntu-latest
142+
143+
steps:
144+
- name: Download all artifacts
145+
uses: actions/download-artifact@v4
146+
with:
147+
path: artifacts
148+
merge-multiple: true
149+
150+
- name: Compute release tag
151+
id: tag
152+
run: |
153+
SHORT_SHA="${GITHUB_SHA:0:7}"
154+
DATE="$(date -u +%Y%m%d)"
155+
echo "value=build-${DATE}-${SHORT_SHA}" >> "$GITHUB_OUTPUT"
156+
157+
- name: Create GitHub release
158+
uses: softprops/action-gh-release@v2
159+
with:
160+
tag_name: ${{ steps.tag.outputs.value }}
161+
name: "Build ${{ steps.tag.outputs.value }}"
162+
prerelease: true
163+
body: |
164+
Automated build from commit ${{ github.sha }}.
165+
166+
**Binaries** — self-contained, no .NET runtime required:
167+
168+
| File | Platform |
169+
|---|---|
170+
| `todo-win-x64.exe` | Windows x64 |
171+
| `todo-linux-x64` | Linux x64 |
172+
| `todo-osx-x64` | macOS Intel |
173+
| `todo-osx-arm64` | macOS Apple Silicon |
174+
175+
Run `chmod +x todo-*` on Linux/macOS before first use.
176+
files: |
177+
artifacts/todo-win-x64.exe
178+
artifacts/todo-linux-x64
179+
artifacts/todo-osx-x64
180+
artifacts/todo-osx-arm64

0 commit comments

Comments
 (0)