diff --git a/backlog/tasks/task-166 - Prevent-AUR-upgrade-cache-collisions-for-unversioned-release-assets.md b/backlog/tasks/task-166 - Prevent-AUR-upgrade-cache-collisions-for-unversioned-release-assets.md new file mode 100644 index 0000000..68eece1 --- /dev/null +++ b/backlog/tasks/task-166 - Prevent-AUR-upgrade-cache-collisions-for-unversioned-release-assets.md @@ -0,0 +1,73 @@ +--- +id: TASK-166 +title: Prevent AUR upgrade cache collisions for unversioned release assets +status: Done +assignee: + - Codex +created_date: '2026-03-17 18:10' +updated_date: '2026-03-17 18:14' +labels: + - release + - packaging + - linux +dependencies: + - TASK-165 +references: + - /home/sudacode/projects/japanese/SubMiner/.github/workflows/release.yml + - /home/sudacode/projects/japanese/SubMiner/scripts/update-aur-package.sh + - /home/sudacode/projects/japanese/SubMiner/scripts/update-aur-package.test.ts + - /home/sudacode/projects/japanese/SubMiner/packaging/aur/subminer-bin/PKGBUILD + - /home/sudacode/projects/japanese/SubMiner/packaging/aur/subminer-bin/.SRCINFO +priority: medium +--- + +## Description + + +Fix the AUR release metadata generated by the tagged-release workflow so end-user upgrades do not reuse stale cached downloads for unversioned `subminer` and `subminer-assets.tar.gz` source names. + + +## Acceptance Criteria + +- [x] #1 AUR packaging generated for a new `pkgver` uses versioned local source aliases for the non-versioned GitHub release assets. +- [x] #2 The package install step references the versioned local launcher filename correctly. +- [x] #3 Regression coverage fails if metadata generation reintroduces stable cache-colliding source aliases. +- [x] #4 Targeted verification records the commands run and results. + + +## Implementation Plan + + +1. Add a failing regression test around `scripts/update-aur-package.sh` output for versioned local source aliases. +2. Update the repo AUR template and `.SRCINFO` rewrite logic to stamp versioned alias names for `subminer` and `subminer-assets`. +3. Verify the generated metadata and targeted workflow/package tests, then record results here. + + +## Implementation Notes + + +Root cause: the AUR package used stable local source aliases for the unversioned `subminer` and `subminer-assets.tar.gz` GitHub release assets. `makepkg`/AUR helpers can reuse those cached filenames across upgrades, so a stale cached download survives into a newer `pkgver` and then fails checksum validation. + +Patched the repo AUR template to version the local cache aliases: +- `subminer-${pkgver}::.../subminer` +- `subminer-assets-${pkgver}.tar.gz::.../subminer-assets.tar.gz` + +Updated `package()` to install the versioned local wrapper filename, and updated `scripts/update-aur-package.sh` so the generated `.SRCINFO` stamps matching concrete versioned aliases for release automation. + +Added regression assertions in `scripts/update-aur-package.test.ts` covering both versioned source aliases and the launcher install path, then watched that test fail before the patch and pass after it. + +Verification: +- `bun test scripts/update-aur-package.test.ts` +- `bash -n scripts/update-aur-package.sh && bash -n packaging/aur/subminer-bin/PKGBUILD` +- `bun run typecheck` +- `bun run test:fast` +- `bun run test:env` +- `bun run build` +- `bun run test:smoke:dist` + + +## Final Summary + + +The tagged-release AUR metadata path now emits versioned local source aliases for the non-versioned GitHub release assets, preventing stale `makepkg` cache reuse across `subminer-bin` upgrades. The change is covered by a regression test and passed the repo's maintained verification gate. + diff --git a/packaging/aur/subminer-bin/.SRCINFO b/packaging/aur/subminer-bin/.SRCINFO index e811334..5f73478 100644 --- a/packaging/aur/subminer-bin/.SRCINFO +++ b/packaging/aur/subminer-bin/.SRCINFO @@ -27,8 +27,8 @@ pkgbase = subminer-bin options = !strip options = !debug source = SubMiner-0.6.2.AppImage::https://github.com/ksyasuda/SubMiner/releases/download/v0.6.2/SubMiner-0.6.2.AppImage - source = subminer::https://github.com/ksyasuda/SubMiner/releases/download/v0.6.2/subminer - source = subminer-assets.tar.gz::https://github.com/ksyasuda/SubMiner/releases/download/v0.6.2/subminer-assets.tar.gz + source = subminer-0.6.2::https://github.com/ksyasuda/SubMiner/releases/download/v0.6.2/subminer + source = subminer-assets-0.6.2.tar.gz::https://github.com/ksyasuda/SubMiner/releases/download/v0.6.2/subminer-assets.tar.gz sha256sums = c91667adbbc47a0fba34855358233454a9ea442ab57510546b2219abd1f2461e sha256sums = 85050918e14cb2512fcd34be83387a2383fa5c206dc1bdc11e8d98f7d37817e5 sha256sums = 210113be64a06840f4dfaebc22a8e6fc802392f1308413aa00d9348c804ab2a1 diff --git a/packaging/aur/subminer-bin/PKGBUILD b/packaging/aur/subminer-bin/PKGBUILD index 20d7aef..c01e73a 100644 --- a/packaging/aur/subminer-bin/PKGBUILD +++ b/packaging/aur/subminer-bin/PKGBUILD @@ -32,8 +32,8 @@ provides=("subminer=${pkgver}") conflicts=('subminer') source=( "SubMiner-${pkgver}.AppImage::https://github.com/ksyasuda/SubMiner/releases/download/v${pkgver}/SubMiner-${pkgver}.AppImage" - "subminer::https://github.com/ksyasuda/SubMiner/releases/download/v${pkgver}/subminer" - "subminer-assets.tar.gz::https://github.com/ksyasuda/SubMiner/releases/download/v${pkgver}/subminer-assets.tar.gz" + "subminer-${pkgver}::https://github.com/ksyasuda/SubMiner/releases/download/v${pkgver}/subminer" + "subminer-assets-${pkgver}.tar.gz::https://github.com/ksyasuda/SubMiner/releases/download/v${pkgver}/subminer-assets.tar.gz" ) sha256sums=( 'c91667adbbc47a0fba34855358233454a9ea442ab57510546b2219abd1f2461e' @@ -50,7 +50,7 @@ package() { install -dm755 "${pkgdir}/opt/SubMiner" ln -s '/opt/SubMiner/SubMiner.AppImage' "${pkgdir}/usr/bin/SubMiner.AppImage" - install -Dm755 "${srcdir}/subminer" "${pkgdir}/usr/bin/subminer" + install -Dm755 "${srcdir}/subminer-${pkgver}" "${pkgdir}/usr/bin/subminer" install -Dm644 "${srcdir}/config.example.jsonc" \ "${pkgdir}/usr/share/SubMiner/config.example.jsonc" diff --git a/scripts/update-aur-package.sh b/scripts/update-aur-package.sh index 0ca2a12..fdd6238 100755 --- a/scripts/update-aur-package.sh +++ b/scripts/update-aur-package.sh @@ -160,13 +160,13 @@ awk \ found_source_appimage = 1 next } - /^\tsource = subminer::https:\/\/github\.com\/ksyasuda\/SubMiner\/releases\/download\/v.*\/subminer$/ { - print "\tsource = subminer::https://github.com/ksyasuda/SubMiner/releases/download/v" version "/subminer" + /^\tsource = subminer-.*::https:\/\/github\.com\/ksyasuda\/SubMiner\/releases\/download\/v.*\/subminer$/ { + print "\tsource = subminer-" version "::https://github.com/ksyasuda/SubMiner/releases/download/v" version "/subminer" found_source_wrapper = 1 next } - /^\tsource = subminer-assets\.tar\.gz::https:\/\/github\.com\/ksyasuda\/SubMiner\/releases\/download\/v.*\/subminer-assets\.tar\.gz$/ { - print "\tsource = subminer-assets.tar.gz::https://github.com/ksyasuda/SubMiner/releases/download/v" version "/subminer-assets.tar.gz" + /^\tsource = subminer-assets-.*\.tar\.gz::https:\/\/github\.com\/ksyasuda\/SubMiner\/releases\/download\/v.*\/subminer-assets\.tar\.gz$/ { + print "\tsource = subminer-assets-" version ".tar.gz::https://github.com/ksyasuda/SubMiner/releases/download/v" version "/subminer-assets.tar.gz" found_source_assets = 1 next } diff --git a/scripts/update-aur-package.test.ts b/scripts/update-aur-package.test.ts index 5a53b54..8189538 100644 --- a/scripts/update-aur-package.test.ts +++ b/scripts/update-aur-package.test.ts @@ -52,12 +52,32 @@ test('update-aur-package updates PKGBUILD and .SRCINFO without makepkg', () => { ); assert.match(pkgbuild, /^pkgver=0\.6\.3$/m); + assert.match( + pkgbuild, + /^\s*"subminer-\$\{pkgver\}::https:\/\/github\.com\/ksyasuda\/SubMiner\/releases\/download\/v\$\{pkgver\}\/subminer"$/m, + ); + assert.match( + pkgbuild, + /^\s*"subminer-assets-\$\{pkgver\}\.tar\.gz::https:\/\/github\.com\/ksyasuda\/SubMiner\/releases\/download\/v\$\{pkgver\}\/subminer-assets\.tar\.gz"$/m, + ); + assert.match( + pkgbuild, + /^\s*install -Dm755 "\$\{srcdir\}\/subminer-\$\{pkgver\}" "\$\{pkgdir\}\/usr\/bin\/subminer"$/m, + ); assert.match(srcinfo, /^\tpkgver = 0\.6\.3$/m); assert.match(srcinfo, /^\tprovides = subminer=0\.6\.3$/m); assert.match( srcinfo, /^\tsource = SubMiner-0\.6\.3\.AppImage::https:\/\/github\.com\/ksyasuda\/SubMiner\/releases\/download\/v0\.6\.3\/SubMiner-0\.6\.3\.AppImage$/m, ); + assert.match( + srcinfo, + /^\tsource = subminer-0\.6\.3::https:\/\/github\.com\/ksyasuda\/SubMiner\/releases\/download\/v0\.6\.3\/subminer$/m, + ); + assert.match( + srcinfo, + /^\tsource = subminer-assets-0\.6\.3\.tar\.gz::https:\/\/github\.com\/ksyasuda\/SubMiner\/releases\/download\/v0\.6\.3\/subminer-assets\.tar\.gz$/m, + ); assert.match(srcinfo, new RegExp(`^\\tsha256sums = ${expectedSums[0]}$`, 'm')); assert.match(srcinfo, new RegExp(`^\\tsha256sums = ${expectedSums[1]}$`, 'm')); assert.match(srcinfo, new RegExp(`^\\tsha256sums = ${expectedSums[2]}$`, 'm'));