mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 02:25:56 +00:00
Retry release asset uploads
This commit is contained in:
@@ -799,13 +799,40 @@ jobs:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
TAG="${{ needs.prepare.outputs.tag }}"
|
||||
gh release upload "${TAG}" release/checksums.txt --clobber
|
||||
gh release upload "${TAG}" release/*.sha256 --clobber
|
||||
release_upload_with_retry() {
|
||||
local attempt=1
|
||||
local max_attempts=5
|
||||
local wait_seconds=15
|
||||
|
||||
while true; do
|
||||
if gh release upload "$@"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$attempt" -ge "$max_attempts" ]; then
|
||||
echo "::error::gh release upload failed after ${max_attempts} attempts: $*"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "gh release upload failed on attempt ${attempt}/${max_attempts}; retrying in ${wait_seconds}s: $*"
|
||||
sleep "$wait_seconds"
|
||||
attempt=$((attempt + 1))
|
||||
if [ "$wait_seconds" -lt 120 ]; then
|
||||
wait_seconds=$((wait_seconds * 2))
|
||||
if [ "$wait_seconds" -gt 120 ]; then
|
||||
wait_seconds=120
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
release_upload_with_retry "${TAG}" release/checksums.txt --clobber
|
||||
release_upload_with_retry "${TAG}" release/*.sha256 --clobber
|
||||
if ls release/*.sig 1> /dev/null 2>&1; then
|
||||
gh release upload "${TAG}" release/*.sig --clobber
|
||||
release_upload_with_retry "${TAG}" release/*.sig --clobber
|
||||
fi
|
||||
if ls release/*.sshsig 1> /dev/null 2>&1; then
|
||||
gh release upload "${TAG}" release/*.sshsig --clobber
|
||||
release_upload_with_retry "${TAG}" release/*.sshsig --clobber
|
||||
fi
|
||||
|
||||
- name: Upload release assets
|
||||
@@ -813,13 +840,40 @@ jobs:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
TAG="${{ needs.prepare.outputs.tag }}"
|
||||
release_upload_with_retry() {
|
||||
local attempt=1
|
||||
local max_attempts=5
|
||||
local wait_seconds=15
|
||||
|
||||
while true; do
|
||||
if gh release upload "$@"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$attempt" -ge "$max_attempts" ]; then
|
||||
echo "::error::gh release upload failed after ${max_attempts} attempts: $*"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "gh release upload failed on attempt ${attempt}/${max_attempts}; retrying in ${wait_seconds}s: $*"
|
||||
sleep "$wait_seconds"
|
||||
attempt=$((attempt + 1))
|
||||
if [ "$wait_seconds" -lt 120 ]; then
|
||||
wait_seconds=$((wait_seconds * 2))
|
||||
if [ "$wait_seconds" -gt 120 ]; then
|
||||
wait_seconds=120
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
if ls release/*.sbom.spdx.json 1> /dev/null 2>&1; then
|
||||
gh release upload "${TAG}" release/*.sbom.spdx.json --clobber
|
||||
release_upload_with_retry "${TAG}" release/*.sbom.spdx.json --clobber
|
||||
fi
|
||||
gh release upload "${TAG}" release/*.tar.gz --clobber
|
||||
gh release upload "${TAG}" release/*.zip --clobber
|
||||
release_upload_with_retry "${TAG}" release/*.tar.gz --clobber
|
||||
release_upload_with_retry "${TAG}" release/*.zip --clobber
|
||||
if ls release/*.tgz 1> /dev/null 2>&1; then
|
||||
gh release upload "${TAG}" release/*.tgz --clobber
|
||||
release_upload_with_retry "${TAG}" release/*.tgz --clobber
|
||||
fi
|
||||
for bare_agent in \
|
||||
release/pulse-agent-linux-amd64 \
|
||||
@@ -833,15 +887,15 @@ jobs:
|
||||
release/pulse-agent-windows-arm64.exe \
|
||||
release/pulse-agent-windows-386.exe; do
|
||||
if [ -f "${bare_agent}" ]; then
|
||||
gh release upload "${TAG}" "${bare_agent}" --clobber
|
||||
release_upload_with_retry "${TAG}" "${bare_agent}" --clobber
|
||||
fi
|
||||
done
|
||||
gh release upload "${TAG}" release/install.sh --clobber
|
||||
release_upload_with_retry "${TAG}" release/install.sh --clobber
|
||||
if [ -f release/install.ps1 ]; then
|
||||
gh release upload "${TAG}" release/install.ps1 --clobber
|
||||
release_upload_with_retry "${TAG}" release/install.ps1 --clobber
|
||||
fi
|
||||
gh release upload "${TAG}" release/install-docker.sh --clobber
|
||||
gh release upload "${TAG}" release/pulse-auto-update.sh --clobber
|
||||
release_upload_with_retry "${TAG}" release/install-docker.sh --clobber
|
||||
release_upload_with_retry "${TAG}" release/pulse-auto-update.sh --clobber
|
||||
|
||||
- name: Publish release
|
||||
if: ${{ github.event.inputs.draft_only != 'true' }}
|
||||
|
||||
@@ -462,6 +462,11 @@ unpublished tag must locate the existing draft release, retarget its git tag
|
||||
and release `target_commitish` to the current governed release-line head, and
|
||||
continue publication without requiring an operator to delete the tag manually;
|
||||
published tags remain immutable and must still fail closed.
|
||||
That same upload boundary must tolerate transient GitHub release-asset API
|
||||
failures. `.github/workflows/create-release.yml` must retry every
|
||||
`gh release upload` operation with bounded backoff before failing the release
|
||||
job, because a single 5xx response during upload can otherwise strand a draft
|
||||
release with a partial asset set and no validation run.
|
||||
That same public release-body boundary also owns publish-safe packet rendering.
|
||||
When operators pass draft packet markdown to `.github/workflows/create-release.yml`,
|
||||
the workflow must sanitize draft-only framing and append the standardized
|
||||
|
||||
@@ -114,7 +114,7 @@ func TestCreateReleaseUploadsPowerShellInstaller(t *testing.T) {
|
||||
`SYFT_ARCHIVE="syft_${SYFT_VERSION}_linux_amd64.tar.gz"`,
|
||||
`SYFT_SHA256="590650c2743b83f327d1bf9bec64f6f83b7fec504187bb84f500c862bf8f2a0f"`,
|
||||
`install -m 0755 "${TMP_DIR}/syft" /usr/local/bin/syft`,
|
||||
`gh release upload "${TAG}" release/*.sbom.spdx.json --clobber`,
|
||||
`release_upload_with_retry "${TAG}" release/*.sbom.spdx.json --clobber`,
|
||||
`release/pulse-agent-linux-amd64`,
|
||||
`release/pulse-agent-linux-arm64`,
|
||||
`release/pulse-agent-linux-armv7`,
|
||||
@@ -125,11 +125,14 @@ func TestCreateReleaseUploadsPowerShellInstaller(t *testing.T) {
|
||||
`release/pulse-agent-windows-amd64.exe`,
|
||||
`release/pulse-agent-windows-arm64.exe`,
|
||||
`release/pulse-agent-windows-386.exe`,
|
||||
`gh release upload "${TAG}" release/install.sh --clobber`,
|
||||
`release_upload_with_retry "${TAG}" release/install.sh --clobber`,
|
||||
`if [ -f release/install.ps1 ]; then`,
|
||||
`gh release upload "${TAG}" release/install.ps1 --clobber`,
|
||||
`gh release upload "${TAG}" release/*.sig --clobber`,
|
||||
`gh release upload "${TAG}" release/*.sshsig --clobber`,
|
||||
`release_upload_with_retry "${TAG}" release/install.ps1 --clobber`,
|
||||
`release_upload_with_retry "${TAG}" release/*.sig --clobber`,
|
||||
`release_upload_with_retry "${TAG}" release/*.sshsig --clobber`,
|
||||
`gh release upload "$@"`,
|
||||
`gh release upload failed on attempt ${attempt}/${max_attempts}; retrying in ${wait_seconds}s`,
|
||||
`gh release upload failed after ${max_attempts} attempts`,
|
||||
`uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4`,
|
||||
`subject-path: release/*`,
|
||||
`gh api "repos/${{ github.repository }}/releases?per_page=100" --paginate`,
|
||||
|
||||
@@ -404,9 +404,12 @@ class ReleasePromotionPolicyTest(unittest.TestCase):
|
||||
self.assertIn('SYFT_ARCHIVE="syft_${SYFT_VERSION}_linux_amd64.tar.gz"', content)
|
||||
self.assertIn('SYFT_SHA256="590650c2743b83f327d1bf9bec64f6f83b7fec504187bb84f500c862bf8f2a0f"', content)
|
||||
self.assertIn('install -m 0755 "${TMP_DIR}/syft" /usr/local/bin/syft', content)
|
||||
self.assertIn('gh release upload "${TAG}" release/*.sig --clobber', content)
|
||||
self.assertIn('gh release upload "${TAG}" release/*.sshsig --clobber', content)
|
||||
self.assertIn('gh release upload "${TAG}" release/*.sbom.spdx.json --clobber', content)
|
||||
self.assertIn('release_upload_with_retry "${TAG}" release/*.sig --clobber', content)
|
||||
self.assertIn('release_upload_with_retry "${TAG}" release/*.sshsig --clobber', content)
|
||||
self.assertIn('release_upload_with_retry "${TAG}" release/*.sbom.spdx.json --clobber', content)
|
||||
self.assertIn('gh release upload "$@"', content)
|
||||
self.assertIn('gh release upload failed on attempt ${attempt}/${max_attempts}; retrying in ${wait_seconds}s', content)
|
||||
self.assertIn('gh release upload failed after ${max_attempts} attempts', content)
|
||||
self.assertIn("provenance: mode=max", content)
|
||||
self.assertIn("sbom: true", content)
|
||||
self.assertIn("id-token: write", content)
|
||||
|
||||
Reference in New Issue
Block a user