Skip to content

Commit ffeaa11

Browse files
committed
fix(release): harden publish workflow
Authenticate cross-repo syncs with an HTTP auth header instead of embedding the raw token in clone URLs.\n\nAlso allow manual release dispatches for an existing tag and prevent Homebrew/Scoop sync failures from blocking GitHub release publication and npm publish.
1 parent 85fa88c commit ffeaa11

File tree

1 file changed

+67
-29
lines changed

1 file changed

+67
-29
lines changed

.github/workflows/release.yml

Lines changed: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,26 @@ on:
55
tags:
66
- "v*"
77
workflow_dispatch:
8+
inputs:
9+
release_tag:
10+
description: "Existing release tag to build and publish (for example v0.1.7)"
11+
required: true
12+
type: string
813

914
permissions:
1015
contents: write
1116

1217
jobs:
1318
verify:
1419
runs-on: ubuntu-latest
20+
env:
21+
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref_name }}
1522

1623
steps:
1724
- name: Checkout
1825
uses: actions/checkout@v6.0.2
26+
with:
27+
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref }}
1928

2029
- name: Install Rust toolchain
2130
uses: dtolnay/rust-toolchain@stable
@@ -33,6 +42,8 @@ jobs:
3342
3443
build:
3544
needs: verify
45+
env:
46+
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref_name }}
3647
strategy:
3748
fail-fast: false
3849
matrix:
@@ -58,6 +69,8 @@ jobs:
5869
steps:
5970
- name: Checkout
6071
uses: actions/checkout@v6.0.2
72+
with:
73+
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref }}
6174

6275
- name: Install Rust toolchain
6376
uses: dtolnay/rust-toolchain@stable
@@ -82,7 +95,7 @@ jobs:
8295
if: runner.os != 'Windows'
8396
env:
8497
TARGET: ${{ matrix.target }}
85-
TAG: ${{ github.ref_name }}
98+
TAG: ${{ env.RELEASE_TAG }}
8699
run: |
87100
mkdir -p dist
88101
cp "target/$TARGET/release/kagi" dist/kagi
@@ -94,7 +107,7 @@ jobs:
94107
shell: pwsh
95108
env:
96109
TARGET: ${{ matrix.target }}
97-
TAG: ${{ github.ref_name }}
110+
TAG: ${{ env.RELEASE_TAG }}
98111
run: |
99112
New-Item -ItemType Directory -Path dist -Force | Out-Null
100113
Copy-Item "target/$env:TARGET/release/kagi.exe" "dist/kagi.exe"
@@ -107,25 +120,29 @@ jobs:
107120
with:
108121
name: release-${{ matrix.target }}
109122
path: |
110-
kagi-${{ github.ref_name }}-${{ matrix.target }}.${{ matrix.archive_ext }}
111-
kagi-${{ github.ref_name }}-${{ matrix.target }}
123+
kagi-${{ env.RELEASE_TAG }}-${{ matrix.target }}.${{ matrix.archive_ext }}
124+
kagi-${{ env.RELEASE_TAG }}-${{ matrix.target }}
112125
113126
- name: Upload packaged assets (windows)
114127
if: runner.os == 'Windows'
115128
uses: actions/upload-artifact@v7.0.0
116129
with:
117130
name: release-${{ matrix.target }}
118131
path: |
119-
kagi-${{ github.ref_name }}-${{ matrix.target }}.${{ matrix.archive_ext }}
120-
kagi-${{ github.ref_name }}-${{ matrix.target }}.exe
132+
kagi-${{ env.RELEASE_TAG }}-${{ matrix.target }}.${{ matrix.archive_ext }}
133+
kagi-${{ env.RELEASE_TAG }}-${{ matrix.target }}.exe
121134
122135
release:
123136
needs: build
124137
runs-on: ubuntu-latest
138+
env:
139+
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref_name }}
125140

126141
steps:
127142
- name: Checkout
128143
uses: actions/checkout@v6.0.2
144+
with:
145+
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref }}
129146

130147
- name: Download packaged archives
131148
uses: actions/download-artifact@v8.0.1
@@ -137,19 +154,21 @@ jobs:
137154
- name: Generate checksums
138155
working-directory: dist
139156
run: |
140-
sha256sum * > "kagi-${GITHUB_REF_NAME}-checksums.txt"
157+
sha256sum * > "kagi-${RELEASE_TAG}-checksums.txt"
141158
142159
- name: Publish GitHub release
143160
env:
144161
GH_TOKEN: ${{ github.token }}
145162
run: |
146-
if gh release view "$GITHUB_REF_NAME" >/dev/null 2>&1; then
147-
gh release upload "$GITHUB_REF_NAME" dist/* --clobber
163+
if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then
164+
gh release upload "$RELEASE_TAG" dist/* --clobber
148165
else
149-
gh release create "$GITHUB_REF_NAME" dist/* --generate-notes --verify-tag
166+
gh release create "$RELEASE_TAG" dist/* --generate-notes --verify-tag
150167
fi
151168
152169
- name: Sync Homebrew tap and Scoop bucket
170+
id: sync_package_indexes
171+
continue-on-error: true
153172
env:
154173
REPO_SYNC_TOKEN: ${{ secrets.REPO_SYNC_TOKEN }}
155174
run: |
@@ -162,26 +181,40 @@ jobs:
162181
163182
SYNC_TOKEN="$(printf '%s' "$REPO_SYNC_TOKEN" | tr -d '\r\n')"
164183
165-
VERSION="${GITHUB_REF_NAME#v}"
166-
CHECKSUM_FILE="dist/kagi-${GITHUB_REF_NAME}-checksums.txt"
167-
BASE_URL="https://github.com/Microck/kagi-cli/releases/download/${GITHUB_REF_NAME}"
184+
VERSION="${RELEASE_TAG#v}"
185+
CHECKSUM_FILE="dist/kagi-${RELEASE_TAG}-checksums.txt"
186+
BASE_URL="https://github.com/Microck/kagi-cli/releases/download/${RELEASE_TAG}"
168187
169188
checksum_for() {
170189
local asset="$1"
171190
grep " ${asset}$" "$CHECKSUM_FILE" | awk '{print $1}'
172191
}
173192
174-
MACOS_ARM_SHA="$(checksum_for "kagi-${GITHUB_REF_NAME}-aarch64-apple-darwin.tar.gz")"
175-
MACOS_INTEL_SHA="$(checksum_for "kagi-${GITHUB_REF_NAME}-x86_64-apple-darwin.tar.gz")"
176-
LINUX_ARM_SHA="$(checksum_for "kagi-${GITHUB_REF_NAME}-aarch64-unknown-linux-gnu.tar.gz")"
177-
LINUX_INTEL_SHA="$(checksum_for "kagi-${GITHUB_REF_NAME}-x86_64-unknown-linux-gnu.tar.gz")"
178-
WINDOWS_INTEL_SHA="$(checksum_for "kagi-${GITHUB_REF_NAME}-x86_64-pc-windows-msvc.zip")"
193+
MACOS_ARM_SHA="$(checksum_for "kagi-${RELEASE_TAG}-aarch64-apple-darwin.tar.gz")"
194+
MACOS_INTEL_SHA="$(checksum_for "kagi-${RELEASE_TAG}-x86_64-apple-darwin.tar.gz")"
195+
LINUX_ARM_SHA="$(checksum_for "kagi-${RELEASE_TAG}-aarch64-unknown-linux-gnu.tar.gz")"
196+
LINUX_INTEL_SHA="$(checksum_for "kagi-${RELEASE_TAG}-x86_64-unknown-linux-gnu.tar.gz")"
197+
WINDOWS_INTEL_SHA="$(checksum_for "kagi-${RELEASE_TAG}-x86_64-pc-windows-msvc.zip")"
179198
180199
TAP_DIR="$(mktemp -d)"
181200
BUCKET_DIR="$(mktemp -d)"
201+
AUTH_HEADER="$(printf 'x-access-token:%s' "$SYNC_TOKEN" | base64 | tr -d '\n')"
182202
183-
git clone "https://x-access-token:${SYNC_TOKEN}@github.com/Microck/homebrew-kagi.git" "$TAP_DIR"
184-
git clone "https://x-access-token:${SYNC_TOKEN}@github.com/Microck/scoop-kagi.git" "$BUCKET_DIR"
203+
clone_with_token() {
204+
local repo="$1"
205+
local dir="$2"
206+
git -c http.https://github.com/.extraheader="AUTHORIZATION: basic ${AUTH_HEADER}" \
207+
clone "https://github.com/${repo}.git" "$dir"
208+
}
209+
210+
push_with_token() {
211+
local dir="$1"
212+
git -C "$dir" -c http.https://github.com/.extraheader="AUTHORIZATION: basic ${AUTH_HEADER}" \
213+
push origin main
214+
}
215+
216+
clone_with_token "Microck/homebrew-kagi" "$TAP_DIR"
217+
clone_with_token "Microck/scoop-kagi" "$BUCKET_DIR"
185218
186219
mkdir -p "$TAP_DIR/Formula"
187220
cat > "$TAP_DIR/Formula/kagi.rb" <<EOF
@@ -193,24 +226,24 @@ jobs:
193226
194227
on_macos do
195228
if Hardware::CPU.arm?
196-
url "${BASE_URL}/kagi-${GITHUB_REF_NAME}-aarch64-apple-darwin.tar.gz"
229+
url "${BASE_URL}/kagi-${RELEASE_TAG}-aarch64-apple-darwin.tar.gz"
197230
sha256 "${MACOS_ARM_SHA}"
198231
end
199232
200233
if Hardware::CPU.intel?
201-
url "${BASE_URL}/kagi-${GITHUB_REF_NAME}-x86_64-apple-darwin.tar.gz"
234+
url "${BASE_URL}/kagi-${RELEASE_TAG}-x86_64-apple-darwin.tar.gz"
202235
sha256 "${MACOS_INTEL_SHA}"
203236
end
204237
end
205238
206239
on_linux do
207240
if Hardware::CPU.arm?
208-
url "${BASE_URL}/kagi-${GITHUB_REF_NAME}-aarch64-unknown-linux-gnu.tar.gz"
241+
url "${BASE_URL}/kagi-${RELEASE_TAG}-aarch64-unknown-linux-gnu.tar.gz"
209242
sha256 "${LINUX_ARM_SHA}"
210243
end
211244
212245
if Hardware::CPU.intel?
213-
url "${BASE_URL}/kagi-${GITHUB_REF_NAME}-x86_64-unknown-linux-gnu.tar.gz"
246+
url "${BASE_URL}/kagi-${RELEASE_TAG}-x86_64-unknown-linux-gnu.tar.gz"
214247
sha256 "${LINUX_INTEL_SHA}"
215248
end
216249
end
@@ -233,7 +266,7 @@ jobs:
233266
"license": "MIT",
234267
"architecture": {
235268
"64bit": {
236-
"url": "${BASE_URL}/kagi-${GITHUB_REF_NAME}-x86_64-pc-windows-msvc.zip",
269+
"url": "${BASE_URL}/kagi-${RELEASE_TAG}-x86_64-pc-windows-msvc.zip",
237270
"hash": "${WINDOWS_INTEL_SHA}"
238271
}
239272
},
@@ -255,14 +288,19 @@ jobs:
255288
git -C "$TAP_DIR" config user.email "contact@micr.dev"
256289
if ! git -C "$TAP_DIR" diff --quiet; then
257290
git -C "$TAP_DIR" add Formula/kagi.rb
258-
git -C "$TAP_DIR" commit -m "chore: update kagi formula for ${GITHUB_REF_NAME}"
259-
git -C "$TAP_DIR" push origin main
291+
git -C "$TAP_DIR" commit -m "chore: update kagi formula for ${RELEASE_TAG}"
292+
push_with_token "$TAP_DIR"
260293
fi
261294
262295
git -C "$BUCKET_DIR" config user.name "Microck"
263296
git -C "$BUCKET_DIR" config user.email "contact@micr.dev"
264297
if ! git -C "$BUCKET_DIR" diff --quiet; then
265298
git -C "$BUCKET_DIR" add kagi.json
266-
git -C "$BUCKET_DIR" commit -m "chore: update kagi manifest for ${GITHUB_REF_NAME}"
267-
git -C "$BUCKET_DIR" push origin main
299+
git -C "$BUCKET_DIR" commit -m "chore: update kagi manifest for ${RELEASE_TAG}"
300+
push_with_token "$BUCKET_DIR"
268301
fi
302+
303+
- name: Report package index sync warning
304+
if: steps.sync_package_indexes.outcome == 'failure'
305+
run: |
306+
echo "::warning title=Package index sync failed::GitHub release assets were published, but Homebrew/Scoop sync did not complete. Check the release job logs."

0 commit comments

Comments
 (0)