fix(release): replace version-independent channel files on 409
latest.yml and release-notes.md change every release, but the atomic publish no longer wipes the channel up front, so their PUTs now hit the previous release's stored file. Swap them in place (delete + put, one small file); version-named payloads keep the same-size keep rule.
This commit is contained in:
1 parent
eccc1f52e7
commit
258e5fac0c
1 file changed
+20
-6
+20
-6
@@ -200,21 +200,35 @@ async function giteaChannel() {
|
||||
for (const [f, name] of ordered) {
|
||||
const stat = fs.statSync(f)
|
||||
const url = `${base}/${encodeURIComponent(name)}`
|
||||
const resp = await fetch(url, {
|
||||
const put = async () =>
|
||||
fetch(url, {
|
||||
method: 'PUT',
|
||||
headers: { Authorization: `token ${env.GIT_TOKEN}`, 'Content-Type': 'application/octet-stream', 'Content-Length': String(stat.size) },
|
||||
body: fs.createReadStream(f),
|
||||
duplex: 'half'
|
||||
})
|
||||
let resp = await put()
|
||||
console.log(` put ${name}: HTTP ${resp.status}`)
|
||||
if (!resp.ok) {
|
||||
const detail = (await resp.text()).slice(0, 200)
|
||||
// Re-publishing the same version can hit an already-stored file; accept it
|
||||
// only when the stored copy has exactly the same size.
|
||||
if ((resp.status === 409 || resp.status === 422) && (await channelFileSize(url)) === stat.size) {
|
||||
if (!resp.ok && (resp.status === 409 || resp.status === 422)) {
|
||||
if (/\d+\.\d+\.\d+/.test(name)) {
|
||||
// Version-named payloads are immutable per release: accept a stored
|
||||
// copy only when it has exactly the same size.
|
||||
if ((await channelFileSize(url)) === stat.size) {
|
||||
console.log(` ${name} is already published with the same size, kept`)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
// latest.yml / release-notes.md change every release and the atomic
|
||||
// flow no longer wipes the channel up front, so replace them in place.
|
||||
// The swap window is one small file (sub-second), not the whole channel.
|
||||
const del = await fetch(url, { method: 'DELETE', headers: { Authorization: `token ${env.GIT_TOKEN}` } })
|
||||
console.log(` delete old ${name}: HTTP ${del.status}`)
|
||||
resp = await put()
|
||||
console.log(` put ${name}: HTTP ${resp.status}`)
|
||||
}
|
||||
}
|
||||
if (!resp.ok) {
|
||||
const detail = (await resp.text()).slice(0, 200)
|
||||
throw new Error(`channel put failed (${resp.status}) for ${name}: ${detail}`)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user