fix(release): harden draft publishing flow
This commit is contained in:
parent
92d4c4cdf9
commit
240bc81d0a
2 changed files with 67 additions and 12 deletions
44
.github/workflows/release.yml
vendored
44
.github/workflows/release.yml
vendored
|
|
@ -9,9 +9,14 @@ on:
|
|||
permissions:
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: release-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
|
@ -56,7 +61,7 @@ jobs:
|
|||
--repo "$GITHUB_REPOSITORY" \
|
||||
--title "$TAG" \
|
||||
--generate-notes \
|
||||
--draft=false 2>/dev/null || echo "Release $TAG already exists, skipping creation"
|
||||
--draft=true 2>/dev/null || echo "Release $TAG already exists, skipping creation"
|
||||
|
||||
- name: Upload dist artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
|
|
@ -69,6 +74,7 @@ jobs:
|
|||
|
||||
prepare-runtime:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
|
@ -84,7 +90,7 @@ jobs:
|
|||
--repo "$GITHUB_REPOSITORY" \
|
||||
--title "$TAG" \
|
||||
--generate-notes \
|
||||
--draft=false 2>/dev/null || echo "Release $TAG already exists, skipping creation"
|
||||
--draft=true 2>/dev/null || echo "Release $TAG already exists, skipping creation"
|
||||
|
||||
- name: Skip runtime asset preparation for manual builds
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
|
||||
|
|
@ -216,6 +222,7 @@ jobs:
|
|||
|
||||
release-mac:
|
||||
needs: [build, prepare-runtime]
|
||||
timeout-minutes: 90
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
@ -318,13 +325,13 @@ jobs:
|
|||
[ -f "$f" ] || continue
|
||||
echo "Uploading: $f"
|
||||
gh release upload "$TAG" "$f" --repo "$GITHUB_REPOSITORY" --clobber 2>&1 || \
|
||||
(sleep 5 && gh release upload "$TAG" "$f" --repo "$GITHUB_REPOSITORY" --clobber 2>&1) || \
|
||||
echo "WARNING: failed to upload $f, continuing..."
|
||||
(sleep 5 && gh release upload "$TAG" "$f" --repo "$GITHUB_REPOSITORY" --clobber 2>&1)
|
||||
done
|
||||
|
||||
release-win:
|
||||
needs: [build, prepare-runtime]
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
|
@ -416,13 +423,13 @@ jobs:
|
|||
[ -f "$f" ] || continue
|
||||
echo "Uploading: $f"
|
||||
gh release upload "$TAG" "$f" --repo "$GITHUB_REPOSITORY" --clobber 2>&1 || \
|
||||
(sleep 5 && gh release upload "$TAG" "$f" --repo "$GITHUB_REPOSITORY" --clobber 2>&1) || \
|
||||
echo "WARNING: failed to upload $f, continuing..."
|
||||
(sleep 5 && gh release upload "$TAG" "$f" --repo "$GITHUB_REPOSITORY" --clobber 2>&1)
|
||||
done
|
||||
|
||||
release-linux:
|
||||
needs: [build, prepare-runtime]
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
|
@ -516,13 +523,13 @@ jobs:
|
|||
[ -f "$f" ] || continue
|
||||
echo "Uploading: $f"
|
||||
gh release upload "$TAG" "$f" --repo "$GITHUB_REPOSITORY" --clobber 2>&1 || \
|
||||
(sleep 5 && gh release upload "$TAG" "$f" --repo "$GITHUB_REPOSITORY" --clobber 2>&1) || \
|
||||
echo "WARNING: failed to upload $f, continuing..."
|
||||
(sleep 5 && gh release upload "$TAG" "$f" --repo "$GITHUB_REPOSITORY" --clobber 2>&1)
|
||||
done
|
||||
|
||||
upload-stable-links:
|
||||
needs: [release-mac, release-win, release-linux]
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
|
||||
steps:
|
||||
|
|
@ -533,7 +540,6 @@ jobs:
|
|||
set -euo pipefail
|
||||
VERSION="${GITHUB_REF#refs/tags/v}"
|
||||
REPO="${GITHUB_REPOSITORY}"
|
||||
DOWNLOAD_BASE="https://github.com/${REPO}/releases/download/v${VERSION}"
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
|
|
@ -551,7 +557,11 @@ jobs:
|
|||
for STABLE_NAME in "${!FILES[@]}"; do
|
||||
VERSIONED_NAME="${FILES[$STABLE_NAME]}"
|
||||
echo "Downloading ${VERSIONED_NAME} -> ${STABLE_NAME}"
|
||||
curl -fSL -o "${TMP_DIR}/${VERSIONED_NAME}" "${DOWNLOAD_BASE}/${VERSIONED_NAME}"
|
||||
gh release download "v${VERSION}" \
|
||||
--repo "$REPO" \
|
||||
--pattern "${VERSIONED_NAME}" \
|
||||
--dir "$TMP_DIR" \
|
||||
--clobber
|
||||
cp "${TMP_DIR}/${VERSIONED_NAME}" "${TMP_DIR}/${STABLE_NAME}"
|
||||
gh release upload "v${VERSION}" "${TMP_DIR}/${STABLE_NAME}" --repo "$REPO" --clobber
|
||||
done
|
||||
|
|
@ -578,7 +588,11 @@ jobs:
|
|||
|
||||
download_asset() {
|
||||
local name="$1"
|
||||
curl -fSL -o "$name" "https://github.com/${REPO}/releases/download/${TAG}/${name}"
|
||||
gh release download "${TAG}" \
|
||||
--repo "${REPO}" \
|
||||
--pattern "$name" \
|
||||
--dir . \
|
||||
--clobber
|
||||
}
|
||||
|
||||
# Canonical Windows feed
|
||||
|
|
@ -636,3 +650,11 @@ jobs:
|
|||
EOF
|
||||
|
||||
gh release upload "${TAG}" latest.yml latest-linux.yml latest-mac.yml --repo "${REPO}" --clobber
|
||||
|
||||
- name: Publish release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
TAG="${GITHUB_REF#refs/tags/}"
|
||||
gh release edit "${TAG}" --repo "${GITHUB_REPOSITORY}" --draft=false --latest
|
||||
|
|
|
|||
|
|
@ -131,6 +131,37 @@ async function downloadFile(url, destinationPath) {
|
|||
await pipeline(Readable.fromWeb(response.body), fs.createWriteStream(destinationPath));
|
||||
}
|
||||
|
||||
function downloadReleaseAssetWithGh(runtimeLock, releaseTag, asset, destinationPath) {
|
||||
if (!process.env.GH_TOKEN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fs.mkdirSync(path.dirname(destinationPath), { recursive: true });
|
||||
const result = spawnSync(
|
||||
'gh',
|
||||
[
|
||||
'release',
|
||||
'download',
|
||||
releaseTag,
|
||||
'--repo',
|
||||
runtimeLock.releaseRepository,
|
||||
'--pattern',
|
||||
asset.file,
|
||||
'--dir',
|
||||
path.dirname(destinationPath),
|
||||
'--clobber',
|
||||
],
|
||||
{
|
||||
cwd: repoRoot,
|
||||
stdio: 'inherit',
|
||||
shell: false,
|
||||
env: process.env,
|
||||
}
|
||||
);
|
||||
|
||||
return result.status === 0 && fs.existsSync(destinationPath);
|
||||
}
|
||||
|
||||
function extractArchive(archivePath, extractDir, archiveKind) {
|
||||
fs.mkdirSync(extractDir, { recursive: true });
|
||||
|
||||
|
|
@ -208,7 +239,9 @@ async function stageRuntime(options) {
|
|||
process.stdout.write(
|
||||
`Downloading ${asset.file} from ${runtimeLock.releaseRepository}@${releaseTag}\n`
|
||||
);
|
||||
await downloadFile(url, archivePath);
|
||||
if (!downloadReleaseAssetWithGh(runtimeLock, releaseTag, asset, archivePath)) {
|
||||
await downloadFile(url, archivePath);
|
||||
}
|
||||
|
||||
process.stdout.write(`Extracting ${asset.file}\n`);
|
||||
extractArchive(archivePath, extractDir, asset.archiveKind);
|
||||
|
|
|
|||
Loading…
Reference in a new issue