chore: merge main into release/v1.1.0 (#42)
Brings the exact tag checks from #40 into the release branch. beta.yaml runs from the branch's own files, and the old prefix-matching lookup treated v1.1.0-beta.1 as a shipped v1.1.0, so the 1.1.0-beta.2 run was refused. The one conflict was in publish_codeberg_release.sh: kept #40's stricter upload handling plus the offline APK assets from #41. scripts/release_gate.sh now reports cut=true for 1.1.0-beta.2. Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de> Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/42
This commit is contained in:
1 parent
c0eb03e5df
commit
89775e44a7
7 files changed
+125
-140
No files matched your search
@@ -3,7 +3,7 @@ name: Beta — Codeberg pre-release
|
|||||||
# A beta is cut by pushing a release branch whose committed versionName is
|
# A beta is cut by pushing a release branch whose committed versionName is
|
||||||
# X.Y.Z-beta.N (see docs/RELEASING.md). Same model as release.yaml: the
|
# X.Y.Z-beta.N (see docs/RELEASING.md). Same model as release.yaml: the
|
||||||
# committed version is the trigger and the vX.Y.Z-beta.N tag is an output. If
|
# committed version is the trigger and the vX.Y.Z-beta.N tag is an output. If
|
||||||
# no tag exists for that version yet, this runs the unit tests, builds and
|
# its Codeberg pre-release doesn't carry the APK yet, this runs the unit tests, builds and
|
||||||
# signs the APK with the app key, records a Gitea pre-release (with the R8
|
# signs the APK with the app key, records a Gitea pre-release (with the R8
|
||||||
# mapping) and publishes a Codeberg pre-release with the APK + SHA-256.
|
# mapping) and publishes a Codeberg pre-release with the APK + SHA-256.
|
||||||
#
|
#
|
||||||
@@ -36,53 +36,23 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Resolve version and whether it is a new beta
|
- name: Resolve version and whether it still needs publishing
|
||||||
id: v
|
id: v
|
||||||
env:
|
|
||||||
# Codeberg, not Gitea: see the same lookup in release.yaml.
|
|
||||||
TAG_API: https://codeberg.org/api/v1/repos/jlmakiola/agendula
|
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
INFO=$(bash scripts/version_info.sh)
|
INFO=$(bash scripts/version_info.sh)
|
||||||
echo "$INFO"
|
echo "$INFO"
|
||||||
echo "$INFO" >> "$GITHUB_OUTPUT"
|
echo "$INFO" >> "$GITHUB_OUTPUT"
|
||||||
VERSION=$(echo "$INFO" | sed -n 's/^version=//p')
|
if [ "$(bash scripts/version_info.sh channel)" != beta ]; then
|
||||||
BASE=$(echo "$INFO" | sed -n 's/^base_version=//p')
|
echo "Not a beta — nothing to do."
|
||||||
if [ "$(echo "$INFO" | sed -n 's/^channel=//p')" != "beta" ]; then
|
|
||||||
echo "versionName $VERSION is not a beta — nothing to do."
|
|
||||||
echo "is_beta=false" >> "$GITHUB_OUTPUT"
|
echo "is_beta=false" >> "$GITHUB_OUTPUT"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
# Fatal on anything but a clean 200/404, as in release.yaml: guessing
|
# Done only once its Codeberg pre-release carries the APK, so a failed
|
||||||
# "no tag" during an outage would re-cut a published beta.
|
# publish is redone by the next push; refused unless newer than the
|
||||||
tag_status() {
|
# latest stable release.
|
||||||
curl -s -o /dev/null -w '%{http_code}' "$TAG_API/git/refs/tags/$1" || echo 000
|
GATE=$(bash scripts/release_gate.sh)
|
||||||
}
|
echo "is_beta=${GATE#cut=}" >> "$GITHUB_OUTPUT"
|
||||||
# A beta of a version that already shipped stable would carry a lower
|
|
||||||
# versionCode than the stable one: nobody could install it over it.
|
|
||||||
case "$(tag_status "v$BASE")" in
|
|
||||||
200)
|
|
||||||
echo "v$BASE already shipped as stable; a beta of it is pointless. Bump the version." >&2
|
|
||||||
exit 1 ;;
|
|
||||||
404) ;;
|
|
||||||
*) echo "Codeberg tag lookup for v$BASE failed — refusing to guess." >&2; exit 1 ;;
|
|
||||||
esac
|
|
||||||
STATUS=$(tag_status "v$VERSION")
|
|
||||||
case "$STATUS" in
|
|
||||||
200)
|
|
||||||
echo "Tag v$VERSION already exists on Codeberg — nothing to release."
|
|
||||||
echo "is_beta=false" >> "$GITHUB_OUTPUT"
|
|
||||||
;;
|
|
||||||
404)
|
|
||||||
echo "No tag for v$VERSION on Codeberg yet — cutting the beta."
|
|
||||||
echo "is_beta=true" >> "$GITHUB_OUTPUT"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Codeberg tag lookup for v$VERSION returned HTTP $STATUS." >&2
|
|
||||||
echo "Refusing to guess: treating this as 'no tag' could re-cut a published beta." >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
beta:
|
beta:
|
||||||
needs: detect
|
needs: detect
|
||||||
|
|||||||
@@ -62,17 +62,6 @@ jobs:
|
|||||||
|
|
||||||
- name: Resolve version and whether it is a new release
|
- name: Resolve version and whether it is a new release
|
||||||
id: v
|
id: v
|
||||||
env:
|
|
||||||
# Tags are read from Codeberg, which is canonical — deliberately NOT
|
|
||||||
# from the Gitea API this workflow runs on. The Codeberg -> Gitea sync
|
|
||||||
# is a push mirror, i.e. `git push --mirror`, which deletes refs the
|
|
||||||
# source does not have. A tag minted here on Gitea is therefore wiped
|
|
||||||
# by the next sync (Codeberg does not have it yet) and only reappears
|
|
||||||
# once the tag push at the end of this workflow propagates back.
|
|
||||||
# Asking Gitea inside that window would report "no tag" for a release
|
|
||||||
# that already shipped, and cut it a second time.
|
|
||||||
# Public repo, so this read needs no token.
|
|
||||||
TAG_API: https://codeberg.org/api/v1/repos/jlmakiola/agendula
|
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
# versionName -> versionCode, channel and the pre-release flag (set
|
# versionName -> versionCode, channel and the pre-release flag (set
|
||||||
@@ -94,30 +83,11 @@ jobs:
|
|||||||
echo "versionName $VERSION on main is a beta. Set the stable version before merging to main." >&2
|
echo "versionName $VERSION on main is a beta. Set the stable version before merging to main." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# A tag for this version already existing means the release shipped on
|
# Tags are read from Codeberg, the canonical forge, by exact name: its
|
||||||
# an earlier push; do nothing. Absent => this merge cuts the release.
|
# git/refs/tags API matches by prefix, so v1.1.0-beta.1 would read as
|
||||||
#
|
# v1.1.0. A lookup error is fatal rather than read as "no tag".
|
||||||
# Anything other than a clean 200/404 is treated as fatal rather than
|
GATE=$(bash scripts/release_gate.sh)
|
||||||
# as "no tag". A Codeberg outage or a network blip would otherwise
|
echo "is_release=${GATE#cut=}" >> "$GITHUB_OUTPUT"
|
||||||
# read as absent and re-cut a release that has already shipped —
|
|
||||||
# republishing to F-Droid. Failing here is recoverable; a duplicate
|
|
||||||
# release is not.
|
|
||||||
STATUS=$(curl -s -o /dev/null -w '%{http_code}' "$TAG_API/git/refs/tags/v$VERSION" || echo 000)
|
|
||||||
case "$STATUS" in
|
|
||||||
200)
|
|
||||||
echo "Tag v$VERSION already exists on Codeberg — nothing to release."
|
|
||||||
echo "is_release=false" >> "$GITHUB_OUTPUT"
|
|
||||||
;;
|
|
||||||
404)
|
|
||||||
echo "No tag for v$VERSION on Codeberg yet — cutting the release."
|
|
||||||
echo "is_release=true" >> "$GITHUB_OUTPUT"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Codeberg tag lookup for v$VERSION returned HTTP $STATUS." >&2
|
|
||||||
echo "Refusing to guess: treating this as 'no tag' could re-cut a shipped release." >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Before a single Gradle task runs: F-Droid truncates the in-client
|
# Before a single Gradle task runs: F-Droid truncates the in-client
|
||||||
# changelog, so an over-long one would reach users cut off mid-sentence.
|
# changelog, so an over-long one would reach users cut off mid-sentence.
|
||||||
|
|||||||
+7
-5
@@ -124,9 +124,11 @@ and to the stable release.
|
|||||||
2. **Optionally verify it on a device** with `scripts/verify-release.sh`, as for
|
2. **Optionally verify it on a device** with `scripts/verify-release.sh`, as for
|
||||||
a stable release.
|
a stable release.
|
||||||
3. **Push the branch to Codeberg.** When it reaches Gitea, `beta.yaml` sees a
|
3. **Push the branch to Codeberg.** When it reaches Gitea, `beta.yaml` sees a
|
||||||
beta version without a tag, runs the unit tests, builds and signs the APK,
|
beta whose Codeberg pre-release doesn't carry its APK yet, runs the unit
|
||||||
creates the `vX.Y.Z-beta.1` tag + a Gitea pre-release (with the R8 mapping)
|
tests, builds and signs the APK, creates the `vX.Y.Z-beta.1` tag + a Gitea
|
||||||
and publishes the **Codeberg pre-release** with the APK + `.sha256`.
|
pre-release (with the R8 mapping) and publishes the **Codeberg
|
||||||
|
pre-release** with the APK + `.sha256`. If that publish fails part-way, the
|
||||||
|
next push of the branch redoes it.
|
||||||
4. **Next round:** bump to `-beta.2` (and its `versionCode`) and push again.
|
4. **Next round:** bump to `-beta.2` (and its `versionCode`) and push again.
|
||||||
5. **Going stable:** set `versionName = "X.Y.Z"` and its `versionCode`
|
5. **Going stable:** set `versionName = "X.Y.Z"` and its `versionCode`
|
||||||
(`1.1.0` → `1010099`), then continue from step 2 of
|
(`1.1.0` → `1010099`), then continue from step 2 of
|
||||||
@@ -142,8 +144,8 @@ Who gets a beta:
|
|||||||
- **Play** never.
|
- **Play** never.
|
||||||
|
|
||||||
Guards: a beta version can't reach `main` (CI fails the PR, and `release.yaml`'s
|
Guards: a beta version can't reach `main` (CI fails the PR, and `release.yaml`'s
|
||||||
`detect` refuses one as a backstop), `beta.yaml` refuses a beta of a version
|
`detect` refuses one as a backstop), `beta.yaml` refuses a beta that isn't
|
||||||
that already shipped stable, and betas start at 1.1.0 (the 1.0.x codes have no
|
newer than the latest stable release, and betas start at 1.1.0 (the 1.0.x codes have no
|
||||||
room below them).
|
room below them).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#This file is generated by updateDaemonJvm
|
#This file is generated by updateDaemonJvm
|
||||||
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/491f83666ae7f4d6ebb28fee72ebb035/redirect
|
toolchainUrl.FREE_BSD.AARCH64=https\://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.11-linux-aarch64-b1163.116.tar.gz
|
||||||
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/0d1a1acdc708062093673f65aa9aba4b/redirect
|
toolchainUrl.FREE_BSD.X86_64=https\://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.11-linux-x64-b1163.116.tar.gz
|
||||||
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/491f83666ae7f4d6ebb28fee72ebb035/redirect
|
toolchainUrl.LINUX.AARCH64=https\://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.11-linux-aarch64-b1163.116.tar.gz
|
||||||
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/0d1a1acdc708062093673f65aa9aba4b/redirect
|
toolchainUrl.LINUX.X86_64=https\://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.11-linux-x64-b1163.116.tar.gz
|
||||||
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/7083b89563e7ce20943037b8cd2b8cc2/redirect
|
toolchainUrl.MAC_OS.AARCH64=https\://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.11-osx-aarch64-b1163.116.tar.gz
|
||||||
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/060bbb778a1f55ea705fdebd2ccfeab9/redirect
|
toolchainUrl.MAC_OS.X86_64=https\://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.11-osx-x64-b1163.116.tar.gz
|
||||||
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/491f83666ae7f4d6ebb28fee72ebb035/redirect
|
toolchainUrl.UNIX.AARCH64=https\://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.11-linux-aarch64-b1163.116.tar.gz
|
||||||
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/0d1a1acdc708062093673f65aa9aba4b/redirect
|
toolchainUrl.UNIX.X86_64=https\://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.11-linux-x64-b1163.116.tar.gz
|
||||||
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/d09679dc60fe5aa05ef7d03efdefac20/redirect
|
toolchainUrl.WINDOWS.AARCH64=https\://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.11-windows-aarch64-b1163.116.tar.gz
|
||||||
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/ed4e3bf2f5e7c5d9aabc4cbd8acd555e/redirect
|
toolchainUrl.WINDOWS.X86_64=https\://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.11-windows-x64-b1163.116.tar.gz
|
||||||
toolchainVendor=JETBRAINS
|
toolchainVendor=JETBRAINS
|
||||||
toolchainVersion=21
|
toolchainVersion=21
|
||||||
@@ -1,24 +1,16 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Publish TAG on Codeberg, which is canonical for tags and releases, with the
|
# Publishes TAG on Codeberg with the signed APK and its SHA-256 attached.
|
||||||
# signed APK and its SHA-256 checksum attached: the direct-download channel
|
# Upserts, so re-runs are safe. A missing TOKEN skips a stable release but fails
|
||||||
# that Obtainium follows. Shared by .gitea/workflows/release.yaml (stable) and
|
# a pre-release, where Codeberg is the only channel.
|
||||||
# beta.yaml (pre-release). Run from the repo checkout: it pushes the tag.
|
|
||||||
#
|
#
|
||||||
# Codeberg push-mirrors branches and tags to Gitea, but releases aren't git
|
# Env: TOKEN, API (.../api/v1/repos/<owner>/<repo>), TAG, SHA, PRERELEASE,
|
||||||
# objects and don't sync in either direction, so this pushes the tag straight
|
# NOTES_FILE, APK, optional APK_OFFLINE (the offline flavor, #39)
|
||||||
# to Codeberg and creates the release over the API. Skips cleanly when TOKEN is
|
|
||||||
# unset; fails loudly on anything else (see release.yaml for why).
|
|
||||||
#
|
|
||||||
# Env:
|
|
||||||
# TOKEN CODEBERG_RELEASE_TOKEN (write:repository); empty = skip
|
|
||||||
# API https://codeberg.org/api/v1/repos/<owner>/<repo>
|
|
||||||
# TAG, SHA vX.Y.Z[-beta.N] and the commit it marks
|
|
||||||
# PRERELEASE true | false
|
|
||||||
# NOTES_FILE release notes (scripts/release_notes.sh)
|
|
||||||
# APK the signed release APK (full flavor)
|
|
||||||
# APK_OFFLINE optional: the signed offline-flavor APK (issue #39)
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
if [ -z "${TOKEN:-}" ]; then
|
if [ -z "${TOKEN:-}" ]; then
|
||||||
|
if [ "${PRERELEASE:-}" = true ]; then
|
||||||
|
echo "CODEBERG_RELEASE_TOKEN not set — a pre-release has nowhere else to go." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
echo "CODEBERG_RELEASE_TOKEN not set — skipping Codeberg publish."
|
echo "CODEBERG_RELEASE_TOKEN not set — skipping Codeberg publish."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
@@ -42,16 +34,8 @@ if [ -n "${APK_OFFLINE:-}" ]; then
|
|||||||
ASSETS+=("$ASSET_OFFLINE" "$ASSET_OFFLINE.sha256")
|
ASSETS+=("$ASSET_OFFLINE" "$ASSET_OFFLINE.sha256")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Push the tag to Codeberg ourselves. Under Codeberg-canonical the mirror runs
|
# Push the tag first and create the release without target_commitish: a POST
|
||||||
# Codeberg -> Gitea, so waiting for a tag to arrive from Gitea (what 0.3.2 did)
|
# naming a commit Codeberg hasn't received yet 500s.
|
||||||
# would wait forever. The tag minted on Gitea is in fact *deleted* by the next
|
|
||||||
# mirror sync until Codeberg has it, so pushing it here is what makes it
|
|
||||||
# durable on both forges.
|
|
||||||
#
|
|
||||||
# Pushing the ref first and creating the release with NO target_commitish is
|
|
||||||
# deliberate: a release POST carrying a target_commitish for a commit or tag
|
|
||||||
# Codeberg hasn't received yet is what produced the empty-bodied 500s.
|
|
||||||
# Attaching to a ref that already exists doesn't need the API to write one.
|
|
||||||
HOST=${API#https://}; HOST=${HOST%%/*}
|
HOST=${API#https://}; HOST=${HOST%%/*}
|
||||||
REPO=${API#*/repos/}
|
REPO=${API#*/repos/}
|
||||||
git tag -f "$TAG" "$SHA"
|
git tag -f "$TAG" "$SHA"
|
||||||
@@ -69,38 +53,38 @@ print(json.dumps({
|
|||||||
}))
|
}))
|
||||||
PY
|
PY
|
||||||
|
|
||||||
# Create (or update) the release. Codeberg 500s on a POST/GET against a tag it
|
# Codeberg 500s on a freshly pushed tag for a few seconds, hence the retries.
|
||||||
# has only just received (the release request outruns the indexing of the ref
|
|
||||||
# pushed a moment ago), so a single attempt can fail even though the very same
|
|
||||||
# call succeeds seconds later. Retry with backoff, and PATCH in place if a
|
|
||||||
# release already exists (re-run safe). A 5xx body still exits curl 0, so the
|
|
||||||
# loop, not `set -e`, controls the flow.
|
|
||||||
ID=""
|
ID=""
|
||||||
for attempt in 1 2 3 4 5 6; do
|
for attempt in 1 2 3 4 5 6; do
|
||||||
EXIST=$(curl -s -H "Authorization: token $TOKEN" "$API/releases/tags/$TAG" | jq -r '.id // empty' 2>/dev/null || true)
|
EXIST=$(curl -s -H "Authorization: token $TOKEN" "$API/releases/tags/$TAG" | jq -r '.id // empty' 2>/dev/null || true)
|
||||||
if [ -n "$EXIST" ]; then
|
if [ -n "$EXIST" ]; then
|
||||||
curl -s -o /dev/null -w "release PATCH HTTP %{http_code}\n" -X PATCH \
|
CODE=$(curl -s -o /dev/null -w '%{http_code}' -X PATCH \
|
||||||
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
|
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
|
||||||
-d @"$WORK/payload.json" "$API/releases/$EXIST"
|
-d @"$WORK/payload.json" "$API/releases/$EXIST" || echo 000)
|
||||||
ID="$EXIST"; break
|
echo "release PATCH HTTP $CODE"
|
||||||
|
if [ "$CODE" = 200 ]; then ID="$EXIST"; break; fi
|
||||||
|
else
|
||||||
|
CODE=$(curl -s -o "$WORK/response.json" -w '%{http_code}' -X POST \
|
||||||
|
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
|
||||||
|
-d @"$WORK/payload.json" "$API/releases" || echo 000)
|
||||||
|
echo "release POST attempt $attempt HTTP $CODE"
|
||||||
|
ID=$(jq -r '.id // empty' "$WORK/response.json" 2>/dev/null || true)
|
||||||
|
[ -n "$ID" ] && break
|
||||||
fi
|
fi
|
||||||
CODE=$(curl -s -o "$WORK/response.json" -w "%{http_code}" -X POST \
|
|
||||||
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
|
|
||||||
-d @"$WORK/payload.json" "$API/releases")
|
|
||||||
echo "release POST attempt $attempt HTTP $CODE"
|
|
||||||
ID=$(jq -r '.id // empty' "$WORK/response.json" 2>/dev/null || true)
|
|
||||||
[ -n "$ID" ] && break
|
|
||||||
sleep $((attempt * 10))
|
sleep $((attempt * 10))
|
||||||
done
|
done
|
||||||
if [ -z "$ID" ]; then echo "Could not resolve Codeberg release id after retries." >&2; exit 1; fi
|
if [ -z "$ID" ]; then echo "Could not create or update the Codeberg release." >&2; exit 1; fi
|
||||||
|
|
||||||
# Attach APKs + checksums, replacing any prior asset of the same name.
|
# Attach APKs + checksums, replacing any prior asset of the same name.
|
||||||
for A in "${ASSETS[@]}"; do
|
for A in "${ASSETS[@]}"; do
|
||||||
OLD=$(curl -s -H "Authorization: token $TOKEN" "$API/releases/$ID/assets" \
|
OLD=$(curl -s -H "Authorization: token $TOKEN" "$API/releases/$ID/assets" \
|
||||||
| jq -r --arg n "$A" '.[] | select(.name==$n) | .id')
|
| jq -r --arg n "$A" '.[]? | select(.name==$n) | .id' 2>/dev/null || true)
|
||||||
[ -n "$OLD" ] && curl -s -X DELETE -H "Authorization: token $TOKEN" "$API/releases/$ID/assets/$OLD" >/dev/null || true
|
for O in $OLD; do
|
||||||
curl -s -X POST -H "Authorization: token $TOKEN" \
|
curl -s -o /dev/null -X DELETE -H "Authorization: token $TOKEN" "$API/releases/$ID/assets/$O" || true
|
||||||
-F "attachment=@$WORK/$A" \
|
done
|
||||||
"$API/releases/$ID/assets?name=$A" -o /dev/null -w "asset $A HTTP %{http_code}\n"
|
CODE=$(curl -s -o /dev/null -w '%{http_code}' -X POST -H "Authorization: token $TOKEN" \
|
||||||
|
-F "attachment=@$WORK/$A" "$API/releases/$ID/assets?name=$A" || echo 000)
|
||||||
|
echo "asset $A HTTP $CODE"
|
||||||
|
if [ "$CODE" != 201 ]; then echo "Uploading $A failed." >&2; exit 1; fi
|
||||||
done
|
done
|
||||||
echo "Published $TAG to Codeberg."
|
echo "Published $TAG to Codeberg."
|
||||||
Executable
+59
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Decides whether the committed version still needs publishing; prints cut=true|false.
|
||||||
|
#
|
||||||
|
# stable: no vX.Y.Z tag on Codeberg yet.
|
||||||
|
# beta: its Codeberg pre-release doesn't carry the APK yet, so a failed
|
||||||
|
# publish is redone by the next push. Refused unless it is newer than
|
||||||
|
# every shipped stable release.
|
||||||
|
#
|
||||||
|
# Fails on any lookup error rather than guessing.
|
||||||
|
set -euo pipefail
|
||||||
|
cd "$(dirname "$0")/.." # repo root
|
||||||
|
|
||||||
|
REPO=${REPO:-jlmakiola/agendula}
|
||||||
|
VERSION=$(bash scripts/version_info.sh version)
|
||||||
|
BASE=$(bash scripts/version_info.sh base_version)
|
||||||
|
CHANNEL=$(bash scripts/version_info.sh channel)
|
||||||
|
|
||||||
|
# Exact tag names. The Codeberg git/refs/tags/<name> API matches by prefix.
|
||||||
|
TAGS=$(git ls-remote --tags --refs "https://codeberg.org/$REPO.git" | sed 's#.*refs/tags/##')
|
||||||
|
|
||||||
|
if [ "$CHANNEL" = stable ]; then
|
||||||
|
if grep -qxF "v$VERSION" <<<"$TAGS"; then
|
||||||
|
echo "Tag v$VERSION already exists on Codeberg — nothing to release." >&2
|
||||||
|
echo "cut=false"
|
||||||
|
else
|
||||||
|
echo "No tag for v$VERSION on Codeberg yet — cutting the release." >&2
|
||||||
|
echo "cut=true"
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
LATEST=$(grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' <<<"$TAGS" | sed 's/^v//' | sort -V | tail -n1 || true)
|
||||||
|
if [ -n "$LATEST" ] && [ "$(printf '%s\n%s\n' "$BASE" "$LATEST" | sort -V | tail -n1)" = "$LATEST" ]; then
|
||||||
|
echo "Beta $VERSION is not newer than the shipped stable $LATEST — bump the version." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ASSET="agendula_v${VERSION}.apk"
|
||||||
|
BODY=$(mktemp); trap 'rm -f "$BODY"' EXIT
|
||||||
|
STATUS=$(curl -s -o "$BODY" -w '%{http_code}' "https://codeberg.org/api/v1/repos/$REPO/releases/tags/v$VERSION" || echo 000)
|
||||||
|
case "$STATUS" in
|
||||||
|
200)
|
||||||
|
if grep -qF "\"name\":\"$ASSET\"" "$BODY"; then
|
||||||
|
echo "Pre-release v$VERSION already carries $ASSET — nothing to do." >&2
|
||||||
|
echo "cut=false"
|
||||||
|
else
|
||||||
|
echo "Pre-release v$VERSION exists without $ASSET — publishing it again." >&2
|
||||||
|
echo "cut=true"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
404)
|
||||||
|
echo "No pre-release for v$VERSION yet — cutting the beta." >&2
|
||||||
|
echo "cut=true"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Codeberg release lookup for v$VERSION returned HTTP $STATUS — refusing to guess." >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -29,12 +29,12 @@ NAME=$(grep -oP 'versionName\s*=\s*"\K[^"]+' "$GRADLE" || true)
|
|||||||
COMMITTED=$(grep -oP 'versionCode\s*=\s*\K[0-9]+' "$GRADLE" || true)
|
COMMITTED=$(grep -oP 'versionCode\s*=\s*\K[0-9]+' "$GRADLE" || true)
|
||||||
[ -n "$NAME" ] || { echo "No versionName in $GRADLE" >&2; exit 1; }
|
[ -n "$NAME" ] || { echo "No versionName in $GRADLE" >&2; exit 1; }
|
||||||
|
|
||||||
if [[ ! "$NAME" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(-beta\.([0-9]+))?$ ]]; then
|
if [[ ! "$NAME" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-beta\.([1-9][0-9]*))?$ ]]; then
|
||||||
echo "versionName '$NAME' is neither X.Y.Z nor X.Y.Z-beta.N" >&2
|
echo "versionName '$NAME' is neither X.Y.Z nor X.Y.Z-beta.N" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
MAJOR=$((10#${BASH_REMATCH[1]})); MINOR=$((10#${BASH_REMATCH[2]})); PATCH=$((10#${BASH_REMATCH[3]}))
|
MAJOR=${BASH_REMATCH[1]}; MINOR=${BASH_REMATCH[2]}; PATCH=${BASH_REMATCH[3]}
|
||||||
BETA=${BASH_REMATCH[5]:+$((10#${BASH_REMATCH[5]}))}
|
BETA=${BASH_REMATCH[5]}
|
||||||
BASE="$MAJOR.$MINOR.$PATCH"
|
BASE="$MAJOR.$MINOR.$PATCH"
|
||||||
|
|
||||||
if [ "$MINOR" -gt 99 ] || [ "$PATCH" -gt 99 ]; then
|
if [ "$MINOR" -gt 99 ] || [ "$PATCH" -gt 99 ]; then
|
||||||
|
|||||||
Reference in new issue
Block a user