Skip to content

Commit 9e1ba9b

Browse files
committed
[build] Local github release automation script.
1 parent 103d041 commit 9e1ba9b

3 files changed

Lines changed: 256 additions & 4 deletions

File tree

build.sh

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ ver_from_manifest() {
5252
grep '"version":' "$1" | sed -re 's/.*": "(.*?)".*/\1/'
5353
}
5454

55+
update_releases() {
56+
bash "$BASE/tools/release.sh" "$VER"
57+
# If this is a pre-release try to update last stable too,
58+
# in case AMO has published its signed XPI in the meanwhile
59+
if [[ $VER =~ \.9[0-9]{2,}$ ]]; then
60+
local STABLE_VER="${VER%.*}"
61+
bash "$BASE/tools/release.sh" "$STABLE_VER"
62+
fi
63+
}
64+
5565
VER=$(ver_from_manifest "$MANIFEST_IN")
5666
if [ "$1" == "tag" ]; then
5767
# ensure nscl is up-to-date git-wise
@@ -246,7 +256,7 @@ build firefox
246256

247257
if [[ $FIREFOX_TARGET == *:tor* ]]; then
248258
if ! [[ $DBG ]]; then
249-
bash "$BASE/tools/deploy2tor.sh" "$MANIFEST_OUT"
259+
bash "$BASE/tools/deploy2tor.sh" "$MANIFEST_OUT" && update_releases
250260
fi
251261
exit
252262
fi
@@ -289,8 +299,7 @@ ZIP=$(build chromium)
289299
if [[ $SIGNED ]] && ! [[ $UNPACKED_ONLY ]] && ! [[ $DBG ]]; then
290300
"$0" tag quiet
291301
nscl
292-
../../we-publish "$XPI.xpi"
293-
302+
"$BASE/../../we-publish" "$XPI.xpi" && update_releases
294303
if ! grep 'Patching ' "$BASE/html5_events/last_run.log" 2>&1; then
295304
echo "WARNING - last IC_EVENT_PATTERN generation run log:" >&2
296305
cat "$BASE/html5_events/last_run.log" >&2

tools/deploy2tor.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,3 @@ pushd "$XPI_DIR" &&
5959
rsync -e "ssh -p $PORT" -avuzP --delete noscript-*1984.xpi noscript-*1984.xpi.gpg update-*.json "$DEST" &&
6060
popd &&
6161
ssh -p $PORT $SRV 'static-update-component dist.torproject.org'
62-
bash $BASE/tools/backfill-tor-tags.sh

tools/release.sh

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
#!/bin/bash
2+
#
3+
# Copyright (C) 2005-2026 Giorgio Maone <https://maone.net>
4+
#
5+
# SPDX-License-Identifier: GPL-3.0-or-later
6+
7+
set -e
8+
9+
OVERWRITE=""
10+
if [[ $1 == "-o" ]]; then
11+
OVERWRITE=true
12+
shift
13+
fi
14+
15+
if ! [[ $1 =~ ^[0-9][0-9.]+$ ]]; then
16+
echo "Usage: $0 [-o] <version>"
17+
echo "-o overwrites existing assets."
18+
echo "Example: $0 13.5.0"
19+
exit 1
20+
fi
21+
22+
VER="$1"
23+
REPO="${GITHUB_REPOSITORY:-$(git config --get remote.origin.url | sed 's|.*github.com[:/]\(.*\)\.git$|\1|')}"
24+
TOKEN="${NS_GH_RELEASE_TOKEN:?Error: NS_GH_RELEASE_TOKEN environment variable must be set}"
25+
26+
if [ -z "$REPO" ]; then
27+
echo "Error: Could not determine repository. Set GITHUB_REPOSITORY or ensure git remote is configured."
28+
exit 1
29+
fi
30+
31+
BASE="$(git rev-parse --show-toplevel)"
32+
33+
find_tag() {
34+
local VER_SHORT="${VER%.0}"
35+
local VER_SHORTER="${VER_SHORT%.0}"
36+
local candidate
37+
for candidate in "$VER" "v$VER" "$VER_SHORT" "v$VER_SHORT" "$VER_SHORTER" "v$VER_SHORTER"; do
38+
if git tag --points-at "$candidate" >/dev/null 2>&1; then
39+
echo "$candidate"
40+
return
41+
fi
42+
done
43+
}
44+
45+
TAG="$(find_tag)"
46+
if ! [[ $TAG ]]; then
47+
echo >&2 "Cannot find tag for $VER"
48+
exit 2
49+
fi
50+
51+
echo "Managing release for version: $VER (tag $TAG) in repository: $REPO"
52+
53+
# Determine if this is a pre-release (ends with .9xx)
54+
LAST_COMPONENT="${VER##*.}"
55+
if [[ "$LAST_COMPONENT" =~ ^9[0-9]{2,}$ ]]; then
56+
PRERELEASE="true"
57+
SUBPATH="betas"
58+
else
59+
PRERELEASE="false"
60+
SUBPATH="releases"
61+
fi
62+
63+
echo "Pre-release: $PRERELEASE"
64+
65+
fetch_file() {
66+
local url="$1"
67+
local fname="$(basename "$url")"
68+
local cached="$BASE/xpi/$fname"
69+
if [[ -f $cached ]] && ( [[ $cached != *.xpi ]] || is_signed "$cached" ); then
70+
echo "$cached"
71+
return
72+
fi
73+
echo >&2 "Downloading $url"
74+
if curl -fsSL --retry 3 -o "$cached" "$url" >/dev/null; then
75+
echo "$cached"
76+
fi
77+
}
78+
79+
# URL encode function for labels
80+
urlencode() {
81+
echo -n "$1" | jq -sRr @uri
82+
}
83+
84+
is_signed() {
85+
[ -f "$1" ] && ( unzip -l "$1" | grep "META-INF/mozilla.rsa" ) >/dev/null 2>&1;
86+
}
87+
88+
# Download available assets
89+
declare -a FILES
90+
declare -a LABELS
91+
92+
93+
FILE="$(fetch_file "https://secure.informaction.com/download/${SUBPATH}/noscript-${VER}-chrome.zip")"
94+
if [[ $FILE ]]; then
95+
FILES+=("$FILE")
96+
LABELS+=("For Chromium (noscript.net/getit/#rc-for-chromium)")
97+
fi
98+
99+
if [[ "$PRERELEASE" == "true" ]]; then
100+
TOR_VER="${VER}01984"
101+
else
102+
TOR_VER="${VER}.1984"
103+
fi
104+
FILE="$(fetch_file "https://dist.torproject.org/torbrowser/noscript/noscript-${TOR_VER}.xpi")"
105+
if [[ $FILE ]]; then
106+
FILES+=("$FILE")
107+
LABELS+=("For Firefox, auto-updated from torproject.org")
108+
fi
109+
110+
FILE="$(fetch_file "https://secure.informaction.com/download/${SUBPATH}/noscript-${VER}.xpi")"
111+
if [[ $FILE ]]; then
112+
FILES+=("$FILE")
113+
if [[ "$PRERELEASE" == "true" ]]; then
114+
LABELS+=("For Firefox, auto-updated from secure.informaction.com")
115+
else
116+
LABELS+=("For Firefox, auto-updated from mozilla.org")
117+
fi
118+
fi
119+
120+
if [ ${#FILES[@]} -eq 0 ]; then
121+
echo "Error: No assets available to upload"
122+
exit 1
123+
fi
124+
125+
echo "Creating changelog..."
126+
if [[ "$PRERELEASE" == "true" ]]; then
127+
# For pre-release: use the regular tag annotation
128+
if [[ -n "$TAG" ]]; then
129+
CHANGELOG=$(git tag -l --format='%(contents)' "$TAG")
130+
echo "Using annotation from tag: $TAG"
131+
else
132+
echo "Warning: No regular tag found for pre-release"
133+
CHANGELOG=""
134+
fi
135+
else
136+
# For stable: fetch from changelog URL
137+
CHANGELOG_VER_ESCAPED="${VER//./\\.}"
138+
CHANGELOG=$(curl -L "https://noscript.net/changelog" 2>/dev/null | \
139+
grep -E -m1 -A1000 "^v? ?$CHANGELOG_VER_ESCAPED$" | \
140+
grep -m1 -B1000 '^$' || true)
141+
142+
if [ -z "$CHANGELOG" ]; then
143+
echo "Warning: Could not fetch changelog from noscript.net"
144+
fi
145+
fi
146+
147+
# Trim, format and append full changelog link
148+
CHANGELOG="$(echo "${CHANGELOG}" | tail -n+3 | sed -re 's/^x /- /')
149+
150+
Full changelog at https://noscript.net/changelog"
151+
echo "$CHANGELOG"
152+
153+
# Prepare release payload
154+
RELEASE_NAME="$VER"
155+
RELEASE_TAG="$TAG"
156+
157+
echo "Checking for existing release with tag: $RELEASE_TAG"
158+
EXISTING_RELEASE=$(curl -fsSL \
159+
-H "Authorization: token $TOKEN" \
160+
"https://api.github.com/repos/$REPO/releases/tags/$RELEASE_TAG" 2>/dev/null || true)
161+
162+
if echo "$EXISTING_RELEASE" | grep -q '"id"'; then
163+
RELEASE_ID=$(echo "$EXISTING_RELEASE" | grep -o '"id": [0-9]*' | head -1 | grep -o '[0-9]*')
164+
echo "Found existing release with ID: $RELEASE_ID"
165+
166+
# Update release metadata
167+
curl -fsSL -X PATCH \
168+
-H "Authorization: token $TOKEN" \
169+
-H "Accept: application/vnd.github.v3+json" \
170+
"https://api.github.com/repos/$REPO/releases/$RELEASE_ID" \
171+
-d "{
172+
\"name\": \"$RELEASE_NAME\",
173+
\"body\": $(printf '%s' "$CHANGELOG" | jq -Rs .),
174+
\"prerelease\": $PRERELEASE
175+
}" > /dev/null
176+
177+
echo "Updated release metadata"
178+
else
179+
echo "Creating new release"
180+
181+
RELEASE_RESPONSE=$(curl -fsSL -X POST \
182+
-H "Authorization: token $TOKEN" \
183+
-H "Accept: application/vnd.github.v3+json" \
184+
"https://api.github.com/repos/$REPO/releases" \
185+
-d "{
186+
\"tag_name\": \"$RELEASE_TAG\",
187+
\"name\": \"$RELEASE_NAME\",
188+
\"body\": $(printf '%s' "$CHANGELOG" | jq -Rs .),
189+
\"prerelease\": $PRERELEASE
190+
}")
191+
192+
RELEASE_ID=$(echo "$RELEASE_RESPONSE" | grep -o '"id": [0-9]*' | head -1 | grep -o '[0-9]*')
193+
echo "Created release with ID: $RELEASE_ID"
194+
fi
195+
196+
# Upload assets
197+
echo "Uploading assets..."
198+
for i in "${!FILES[@]}"; do
199+
FILE="${FILES[$i]}"
200+
LABEL="${LABELS[$i]}"
201+
FILENAME=$(basename "$FILE")
202+
203+
# URL encode the label
204+
ENCODED_LABEL=$(urlencode "$LABEL")
205+
206+
echo "Uploading $FILENAME with label $LABEL"
207+
208+
# Delete existing asset if present
209+
ASSET_ID=$(curl -fsSL \
210+
-H "Authorization: token $TOKEN" \
211+
"https://api.github.com/repos/$REPO/releases/$RELEASE_ID/assets" | \
212+
jq -r ".[] | select(.name == \"$FILENAME\") | .id" | head -1)
213+
214+
if [ -n "$ASSET_ID" ] && [ "$ASSET_ID" != "null" ]; then
215+
if ! [[ $OVERWRITE ]]; then
216+
echo "Skipping existing asset: $FILENAME"
217+
continue
218+
fi
219+
echo "Deleting existing asset: $FILENAME"
220+
curl -fsSL -X DELETE \
221+
-H "Authorization: token $TOKEN" \
222+
"https://api.github.com/repos/$REPO/releases/assets/$ASSET_ID" > /dev/null
223+
fi
224+
225+
UPLOAD_RESPONSE=$(curl -fsSL -X POST \
226+
-H "Authorization: token $TOKEN" \
227+
-H "Content-Type: application/octet-stream" \
228+
"https://uploads.github.com/repos/$REPO/releases/$RELEASE_ID/assets?name=$FILENAME&label=$ENCODED_LABEL" \
229+
--data-binary "@$FILE" \
230+
-w "\n%{http_code}" || true)
231+
232+
HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | tail -1)
233+
RESPONSE_BODY=$(echo "$UPLOAD_RESPONSE" | sed '$d')
234+
235+
if [ "$HTTP_CODE" = "201" ]; then
236+
echo "✓ Uploaded: $FILENAME"
237+
else
238+
echo "✗ Upload failed with HTTP $HTTP_CODE"
239+
echo "Response: $RESPONSE_BODY"
240+
exit 1
241+
fi
242+
done
243+
244+
echo "Release: https://github.com/$REPO/releases/tag/$RELEASE_TAG"

0 commit comments

Comments
 (0)