-
-
Notifications
You must be signed in to change notification settings - Fork 0
226 lines (192 loc) · 8.08 KB
/
Copy pathrelease.yml
File metadata and controls
226 lines (192 loc) · 8.08 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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
name: Release
on:
push:
tags:
- 'v*'
env:
APP_NAME: Hinto
SCHEME: Hinto
BUILD_PATH: build/Build/Products/Release
MACOS_MIN_VERSION: "13.0" # Keep in sync with Config/base.xcconfig
jobs:
release:
runs-on: macos-latest
environment: production
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get version from tag
id: version
run: |
VERSION=${GITHUB_REF#refs/tags/v}
./Scripts/ci/validate-release-version.sh "$VERSION"
BUILD_NUMBER=$(./Scripts/ci/version-to-build-number.sh "$VERSION")
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "build_number=$BUILD_NUMBER" >> $GITHUB_OUTPUT
echo "Releasing version: $VERSION (build $BUILD_NUMBER)"
- name: Install certificate
env:
APPLE_CERTIFICATE_P12: ${{ secrets.APPLE_CERTIFICATE_P12 }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
run: |
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
KEYCHAIN_PASSWORD=password
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security default-keychain -s "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
echo "$APPLE_CERTIFICATE_P12" | base64 --decode > $RUNNER_TEMP/certificate.p12
security import $RUNNER_TEMP/certificate.p12 \
-P "$APPLE_CERTIFICATE_PASSWORD" \
-T /usr/bin/codesign \
-k "$KEYCHAIN_PATH"
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
- name: Build
env:
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
xcodebuild \
-scheme $SCHEME \
-configuration Release \
-derivedDataPath build \
CODE_SIGN_IDENTITY="Developer ID Application" \
CODE_SIGN_STYLE=Manual \
DEVELOPMENT_TEAM="$APPLE_TEAM_ID" \
CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO \
OTHER_CODE_SIGN_FLAGS="--timestamp --options runtime" \
build
- name: Re-sign Sparkle framework
run: |
APP_PATH="$BUILD_PATH/$APP_NAME.app"
SPARKLE_PATH="$APP_PATH/Contents/Frameworks/Sparkle.framework"
# Sign Sparkle components (inner to outer)
codesign --force --options runtime --timestamp \
--sign "Developer ID Application" \
"$SPARKLE_PATH/Versions/B/XPCServices/Downloader.xpc"
codesign --force --options runtime --timestamp \
--sign "Developer ID Application" \
"$SPARKLE_PATH/Versions/B/XPCServices/Installer.xpc"
codesign --force --options runtime --timestamp \
--sign "Developer ID Application" \
"$SPARKLE_PATH/Versions/B/Autoupdate"
codesign --force --options runtime --timestamp \
--sign "Developer ID Application" \
"$SPARKLE_PATH/Versions/B/Updater.app"
codesign --force --options runtime --timestamp \
--sign "Developer ID Application" \
"$SPARKLE_PATH"
# Re-sign the main app
codesign --force --options runtime --timestamp \
--sign "Developer ID Application" \
--entitlements Resources/Hinto.entitlements \
"$APP_PATH"
- name: Notarize
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
cd "$BUILD_PATH"
ditto -c -k --keepParent "$APP_NAME.app" "$APP_NAME.zip"
xcrun notarytool submit "$APP_NAME.zip" \
--apple-id "$APPLE_ID" \
--password "$APPLE_PASSWORD" \
--team-id "$APPLE_TEAM_ID" \
--wait
xcrun stapler staple "$APP_NAME.app"
- name: Create DMG
run: |
git clone https://github.com/create-dmg/create-dmg.git
./create-dmg/create-dmg \
--volname "$APP_NAME" \
--window-pos 200 120 \
--window-size 500 320 \
--icon-size 80 \
--icon "$APP_NAME.app" 125 175 \
--hide-extension "$APP_NAME.app" \
--app-drop-link 375 175 \
--no-internet-enable \
"$APP_NAME.dmg" \
"$BUILD_PATH/$APP_NAME.app"
- name: Sign DMG for Sparkle
id: sparkle_sign
env:
SPARKLE_PRIVATE_KEY: ${{ secrets.SPARKLE_PRIVATE_KEY }}
run: |
# Download Sparkle tools
SPARKLE_VERSION="2.6.4"
curl -L -o /tmp/Sparkle.tar.xz "https://github.com/sparkle-project/Sparkle/releases/download/${SPARKLE_VERSION}/Sparkle-${SPARKLE_VERSION}.tar.xz"
mkdir -p /tmp/sparkle
tar -xf /tmp/Sparkle.tar.xz -C /tmp/sparkle
# Sign the DMG with EdDSA key
echo "$SPARKLE_PRIVATE_KEY" > /tmp/sparkle_key
SIGN_OUTPUT=$(/tmp/sparkle/bin/sign_update "$APP_NAME.dmg" --ed-key-file /tmp/sparkle_key)
rm -f /tmp/sparkle_key
echo "sign_update output: $SIGN_OUTPUT"
# Extract just the signature value from: sparkle:edSignature="xxx" length="xxx"
SIGNATURE=$(echo "$SIGN_OUTPUT" | sed -n 's/.*sparkle:edSignature="\([^"]*\)".*/\1/p')
echo "signature=$SIGNATURE" >> $GITHUB_OUTPUT
echo "Extracted signature: $SIGNATURE"
# Get DMG size
DMG_SIZE=$(stat -f%z "$APP_NAME.dmg")
echo "dmg_size=$DMG_SIZE" >> $GITHUB_OUTPUT
- name: Extract release notes from CHANGELOG
id: changelog
run: |
VERSION=${{ steps.version.outputs.version }}
# Extract content between current version and next version header (or EOF)
# Trim leading/trailing blank lines while preserving internal blank lines
NOTES=$(awk '
/^## \['"$VERSION"'\]/ { flag=1; next }
/^## \[/ { flag=0 }
flag { lines[++n] = $0 }
END {
start = 1; while (start <= n && lines[start] == "") start++
end = n; while (end >= start && lines[end] == "") end--
for (i = start; i <= end; i++) print lines[i]
}
' Resources/CHANGELOG.md)
# Handle multiline output
echo "notes<<EOF" >> $GITHUB_OUTPUT
echo "$NOTES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: ${{ env.APP_NAME }}.dmg
body: |
${{ steps.changelog.outputs.notes }}
---
**Installation:** Download `Hinto.dmg`, open it, and drag Hinto to your Applications folder.
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy appcast.xml to GitHub Pages
env:
VERSION: ${{ steps.version.outputs.version }}
BUILD_NUMBER: ${{ steps.version.outputs.build_number }}
SIGNATURE: ${{ steps.sparkle_sign.outputs.signature }}
DMG_SIZE: ${{ steps.sparkle_sign.outputs.dmg_size }}
MACOS_MIN_VERSION: ${{ env.MACOS_MIN_VERSION }}
REPO_URL: https://github.com/yhao3/hinto
APPCAST_URL: https://yhao3.github.io/hinto/appcast.xml
run: ./Scripts/ci/deploy-appcast.sh
- name: Update website version
env:
VERSION: ${{ steps.version.outputs.version }}
HINTO_SITE_PAT: ${{ secrets.HINTO_SITE_PAT }}
run: |
curl -X POST \
-H "Authorization: token $HINTO_SITE_PAT" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/yhao3/hinto-site/dispatches \
-d "{\"event_type\":\"release\",\"client_payload\":{\"version\":\"$VERSION\"}}"
- name: Cleanup
if: always()
run: |
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db || true
rm -f $RUNNER_TEMP/certificate.p12