Repository navigation
174 lines (162 loc) · 7.75 KB
/
Copy pathrelease.yml
File metadata and controls
174 lines (162 loc) · 7.75 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
name: Release
# Nur auf Tags. Niemals auf Pull Requests: Der Auftrag braucht die
# Signaturschluessel, und ein fremder Fork darf nie an sie herankommen.
on:
push:
tags: ["v*"]
permissions:
contents: write
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
env:
# Werkzeuge von Sparkle (generate_appcast). Feste Fassung mit Pruefsumme -
# das Werkzeug signiert Updates, es darf sich nicht unbemerkt aendern.
SPARKLE_VERSION: 2.10.0
SPARKLE_SHA256: c2bf58aa8387266ac179357b1415d6f2635f044da8be41042af32425dae6da0c
REPO_URL: https://github.com/Silvertree2010/ApolloShell
jobs:
release:
name: Build, sign and publish
runs-on: macos-26
timeout-minutes: 60
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Die ganze Vorgeschichte: scripts/assemble-app.sh zaehlt die
# Commits fuer CFBundleVersion. Mit der flachen Voreinstellung waere
# jede Fassung Build 1 - und Sparkle vergleicht genau diese Zahl,
# also waere kein Release je neuer als das vorige.
fetch-depth: 0
- name: Check that the tag matches the bundle version
run: |
set -o pipefail
tag="${GITHUB_REF_NAME#v}"
plist=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' Support/Info.plist)
if [ "$tag" != "$plist" ]; then
echo "Tag $GITHUB_REF_NAME passt nicht zu CFBundleShortVersionString $plist" >&2
exit 1
fi
key=$(/usr/libexec/PlistBuddy -c 'Print :SUPublicEDKey' Support/Info.plist)
if [ -z "$key" ]; then
echo "SUPublicEDKey fehlt in Support/Info.plist (scripts/make-release-keys.sh)" >&2
exit 1
fi
- name: Import the release certificate
env:
CERT_P12: ${{ secrets.RELEASE_CERT_P12 }}
CERT_PASSWORD: ${{ secrets.RELEASE_CERT_PASSWORD }}
run: |
keychain="$RUNNER_TEMP/release.keychain-db"
pass=$(uuidgen)
security create-keychain -p "$pass" "$keychain"
security set-keychain-settings -lut 3600 "$keychain"
security unlock-keychain -p "$pass" "$keychain"
printf '%s' "$CERT_P12" | base64 --decode > "$RUNNER_TEMP/release-cert.p12"
security import "$RUNNER_TEMP/release-cert.p12" -k "$keychain" -P "$CERT_PASSWORD" \
-T /usr/bin/codesign -A
security set-key-partition-list -S apple-tool:,apple: -s -k "$pass" "$keychain" >/dev/null
# In die Suchliste, damit `security find-identity` es findet
# (scripts/assemble-app.sh fragt genau so).
security list-keychains -d user -s "$keychain" $(security list-keychains -d user | tr -d '"')
rm -f "$RUNNER_TEMP/release-cert.p12"
- name: Build the universal DMG
env:
SIGN_IDENTITY: ApolloShell Release Signing
run: |
set -o pipefail
scripts/make-dmg.sh
codesign --verify --deep --strict --verbose=2 "build/dist/ApolloShell.app"
# Ad-hoc signiert waere die Pruefung oben auch zufrieden, aber dann
# waere nach jedem Update jede Bedienungshilfen-Freigabe der Nutzer
# weg. Also ausdruecklich nachsehen, wer unterschrieben hat.
codesign -dvv "build/dist/ApolloShell.app" 2>&1 | grep -q "Authority=ApolloShell Release Signing"
build=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' "build/dist/ApolloShell.app/Contents/Info.plist")
if [ "$build" -le 1 ]; then
echo "CFBundleVersion ist $build - Sparkle koennte kein Update vom naechsten unterscheiden" >&2
exit 1
fi
- name: Fetch the Sparkle tools
run: |
set -o pipefail
curl -fsSL -o "$RUNNER_TEMP/sparkle.tar.xz" \
"https://github.com/sparkle-project/Sparkle/releases/download/$SPARKLE_VERSION/Sparkle-$SPARKLE_VERSION.tar.xz"
echo "$SPARKLE_SHA256 $RUNNER_TEMP/sparkle.tar.xz" | shasum -a 256 -c -
mkdir -p "$RUNNER_TEMP/sparkle"
tar -xf "$RUNNER_TEMP/sparkle.tar.xz" -C "$RUNNER_TEMP/sparkle" ./bin/generate_appcast
- name: Generate and sign the appcast
env:
SPARKLE_EDDSA_KEY: ${{ secrets.SPARKLE_EDDSA_KEY }}
GH_TOKEN: ${{ github.token }}
run: |
set -o pipefail
# Frueheren Appcast dazunehmen, damit die Liste der Fassungen
# erhalten bleibt. Beim ersten Release gibt es noch keinen.
gh release download --repo "$GITHUB_REPOSITORY" --pattern appcast.xml --dir dist || true
printf '%s' "$SPARKLE_EDDSA_KEY" | "$RUNNER_TEMP/sparkle/bin/generate_appcast" \
--ed-key-file - \
--download-url-prefix "$REPO_URL/releases/download/$GITHUB_REF_NAME/" \
--full-release-notes-url "$REPO_URL/blob/main/CHANGELOG.md" \
--link "$REPO_URL" \
dist
test -s dist/appcast.xml
- name: Publish the release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -o pipefail
version="${GITHUB_REF_NAME#v}"
# Vier Teile heissen "0.1.2 Patch 2", drei bleiben "0.1.2" - so
# wie die Releases von Hand benannt waren.
case "$version" in
*.*.*.*) title="ApolloShell ${version%.*} Patch ${version##*.}" ;;
*) title="ApolloShell $version" ;;
esac
# Die Notizen sind der Abschnitt der Fassung aus dem Changelog,
# nicht nur ein Verweis darauf.
notes=$(scripts/release-notes.sh "$version")
if [ -z "$notes" ]; then
notes="See [CHANGELOG.md]($REPO_URL/blob/main/CHANGELOG.md)."
fi
gh release create "$GITHUB_REF_NAME" \
--repo "$GITHUB_REPOSITORY" \
--verify-tag \
--title "$title" \
--notes "$notes" \
"dist/ApolloShell-$version.dmg" \
dist/appcast.xml
- name: Update the Homebrew tap
env:
TAP_DEPLOY_KEY: ${{ secrets.TAP_DEPLOY_KEY }}
run: |
set -o pipefail
version="${GITHUB_REF_NAME#v}"
tarball="$REPO_URL/archive/refs/tags/$GITHUB_REF_NAME.tar.gz"
# Dasselbe Archiv, das Homebrew spaeter laedt.
curl -fsSL -o "$RUNNER_TEMP/source.tar.gz" "$tarball"
sha=$(shasum -a 256 "$RUNNER_TEMP/source.tar.gz" | cut -d' ' -f1)
if [ -z "$sha" ]; then
echo "keine Pruefsumme fuer $tarball" >&2
exit 1
fi
# Schreibrecht ueber einen Deploy-Key, der nur fuer das Tap-Repo
# gilt - kein Token, das auf alle Repos passt, und nichts, was in
# der Adresse oder in .git/config liegen bleibt.
mkdir -p "$RUNNER_TEMP/ssh"
printf '%s\n' "$TAP_DEPLOY_KEY" > "$RUNNER_TEMP/ssh/id"
chmod 600 "$RUNNER_TEMP/ssh/id"
export GIT_SSH_COMMAND="ssh -i $RUNNER_TEMP/ssh/id -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=$RUNNER_TEMP/ssh/known_hosts"
git clone --depth 1 git@github.com:Silvertree2010/homebrew-apolloshell.git "$RUNNER_TEMP/tap"
formula="$RUNNER_TEMP/tap/Formula/apolloshell.rb"
/usr/bin/sed -i '' -e "s|url \".*\"|url \"$tarball\"|" -e "s|sha256 \".*\"|sha256 \"$sha\"|" "$formula"
# Steht die Formel schon richtig (erneuter Lauf desselben Tags),
# ist das kein Fehler - das Release ist da, nur die Formel war es
# schon.
if git -C "$RUNNER_TEMP/tap" diff --quiet; then
echo "Formel steht schon auf $version"
exit 0
fi
git -C "$RUNNER_TEMP/tap" -c user.name="ApolloShell Release" \
-c user.email="noreply@github.com" \
commit -am "ApolloShell $version"
git -C "$RUNNER_TEMP/tap" push