Shelly's static-URL mode polls one constant URL with a HEAD request and compares ETag (falling back to Last-Modified). Gitea 1.27 has no /releases/latest/download/ redirect and release URLs always contain the tag, so there was no constant URL.
What
After the versioned release is published, .gitea/scripts/update-latest.sh replaces the AppImage on a rolling pre-release tagged latest:
Pre-release, so Gitea's own "latest release" stays the newest vX.Y.Z (verified).
The publish job now checks out first: actions/checkout cleans the workspace and would delete the downloaded artifacts if it ran after them.
Testing
Ran the script against the live API twice (create, then replace) using the v1.0.1 CI AppImage. The URL stayed constant and the ETag changed on replace. The latest release is already seeded with v1.0.1.
Not tested: the workflow step itself, which only runs on a v* tag. First real exercise will be the next release.
## Why
Shelly's static-URL mode polls one constant URL with a HEAD request and compares `ETag` (falling back to `Last-Modified`). Gitea 1.27 has no `/releases/latest/download/` redirect and release URLs always contain the tag, so there was no constant URL.
## What
After the versioned release is published, `.gitea/scripts/update-latest.sh` replaces the AppImage on a rolling pre-release tagged `latest`:
`https://repo.anhonesthost.net/streamer-tools/whats-that-music/releases/download/latest/WhatsThatMusic-latest-linux-x86_64.AppImage`
- Pre-release, so Gitea's own "latest release" stays the newest `vX.Y.Z` (verified).
- The publish job now checks out first: `actions/checkout` cleans the workspace and would delete the downloaded artifacts if it ran after them.
## Testing
Ran the script against the live API twice (create, then replace) using the v1.0.1 CI AppImage. The URL stayed constant and the ETag changed on replace. The `latest` release is already seeded with v1.0.1.
Not tested: the workflow step itself, which only runs on a `v*` tag. First real exercise will be the next release.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Gitea has no /releases/latest/download/ redirect and release URLs always
include the tag, so updaters that poll a constant URL (Shelly) cannot use
them. After publishing a vX.Y.Z release, replace the asset on a rolling
pre-release tagged "latest":
.../releases/download/latest/WhatsThatMusic-latest-linux-x86_64.AppImage
Replacing the asset changes its ETag and Last-Modified, which Shelly
compares. The pre-release flag keeps Gitea's own "latest release" on the
newest vX.Y.Z. The logic lives in .gitea/scripts/update-latest.sh so it can
be run against the API outside CI. The publish job now checks out first,
since checkout cleans the workspace and would delete downloaded artifacts.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
jknapp
merged commit d3a67688f8 into main2026-10-04 19:19:40 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Why
Shelly's static-URL mode polls one constant URL with a HEAD request and compares
ETag(falling back toLast-Modified). Gitea 1.27 has no/releases/latest/download/redirect and release URLs always contain the tag, so there was no constant URL.What
After the versioned release is published,
.gitea/scripts/update-latest.shreplaces the AppImage on a rolling pre-release taggedlatest:https://repo.anhonesthost.net/streamer-tools/whats-that-music/releases/download/latest/WhatsThatMusic-latest-linux-x86_64.AppImagevX.Y.Z(verified).actions/checkoutcleans the workspace and would delete the downloaded artifacts if it ran after them.Testing
Ran the script against the live API twice (create, then replace) using the v1.0.1 CI AppImage. The URL stayed constant and the ETag changed on replace. The
latestrelease is already seeded with v1.0.1.Not tested: the workflow step itself, which only runs on a
v*tag. First real exercise will be the next release.🤖 Generated with Claude Code