mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 14:35:41 +00:00
fix(release): restore known-good publish workflow baseline (#415)
Reset reusable channel publish to the last known-good release flow from b83c0f5 and keep build_platform_artifacts gating for source-only dispatch compatibility.
This commit is contained in:
@@ -40,7 +40,7 @@ jobs:
|
|||||||
contents: write
|
contents: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
release_id: ${{ steps.create_release.outputs.release_id }}
|
release_id: ${{ steps.create-release.outputs.result }}
|
||||||
package_version: ${{ steps.get-version.outputs.version }}
|
package_version: ${{ steps.get-version.outputs.version }}
|
||||||
release_tag: ${{ steps.tag.outputs.value }}
|
release_tag: ${{ steps.tag.outputs.value }}
|
||||||
source_commit_sha: ${{ steps.source-sha.outputs.value }}
|
source_commit_sha: ${{ steps.source-sha.outputs.value }}
|
||||||
@@ -94,7 +94,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
echo "value=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
echo "value=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||||
- name: ensure tag points to source ref
|
- name: align existing tag to source ref
|
||||||
env:
|
env:
|
||||||
TAG: ${{ steps.tag.outputs.value }}
|
TAG: ${{ steps.tag.outputs.value }}
|
||||||
EXPECTED_SHA: ${{ steps.source-sha.outputs.value }}
|
EXPECTED_SHA: ${{ steps.source-sha.outputs.value }}
|
||||||
@@ -108,11 +108,7 @@ jobs:
|
|||||||
echo "::warning::Re-pointing tag '$TAG' to expected source commit to keep Source code archives aligned with built artifacts."
|
echo "::warning::Re-pointing tag '$TAG' to expected source commit to keep Source code archives aligned with built artifacts."
|
||||||
git tag -f "$TAG" "$EXPECTED_SHA"
|
git tag -f "$TAG" "$EXPECTED_SHA"
|
||||||
git push --force origin "refs/tags/$TAG"
|
git push --force origin "refs/tags/$TAG"
|
||||||
else
|
|
||||||
echo "Tag '$TAG' already points to expected source commit $EXPECTED_SHA"
|
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
echo "Tag '$TAG' does not exist yet; it will be created by createRelease with target_commitish=$EXPECTED_SHA."
|
|
||||||
fi
|
fi
|
||||||
- name: extract changelog
|
- name: extract changelog
|
||||||
id: changelog
|
id: changelog
|
||||||
@@ -130,8 +126,8 @@ jobs:
|
|||||||
echo "$BODY" >> "$GITHUB_OUTPUT"
|
echo "$BODY" >> "$GITHUB_OUTPUT"
|
||||||
echo "$EOF_MARKER" >> "$GITHUB_OUTPUT"
|
echo "$EOF_MARKER" >> "$GITHUB_OUTPUT"
|
||||||
- name: create or update release
|
- name: create or update release
|
||||||
id: create_release
|
id: create-release
|
||||||
uses: actions/github-script@v9
|
uses: actions/github-script@v7
|
||||||
env:
|
env:
|
||||||
PACKAGE_VERSION: ${{ steps.get-version.outputs.version }}
|
PACKAGE_VERSION: ${{ steps.get-version.outputs.version }}
|
||||||
RELEASE_TAG: ${{ steps.tag.outputs.value }}
|
RELEASE_TAG: ${{ steps.tag.outputs.value }}
|
||||||
@@ -142,158 +138,42 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const tag = process.env.RELEASE_TAG;
|
const tag = process.env.RELEASE_TAG;
|
||||||
const targetCommitish = process.env.RELEASE_COMMIT_SHA;
|
|
||||||
const version = process.env.PACKAGE_VERSION;
|
|
||||||
const body = process.env.CHANGELOG_BODY || "See the assets to download this version and install.";
|
const body = process.env.CHANGELOG_BODY || "See the assets to download this version and install.";
|
||||||
const prerelease = process.env.IS_PRERELEASE === "true";
|
const prerelease = process.env.IS_PRERELEASE === "true";
|
||||||
const draft = process.env.IS_DRAFT === "true";
|
const draft = process.env.IS_DRAFT === "true";
|
||||||
|
const version = process.env.PACKAGE_VERSION;
|
||||||
|
const targetCommitish = process.env.RELEASE_COMMIT_SHA;
|
||||||
const name = `Psysonic v${version}`;
|
const name = `Psysonic v${version}`;
|
||||||
|
|
||||||
if (!tag || !/^app-v\d+\.\d+\.\d+(?:[-+].+)?$/.test(tag)) {
|
|
||||||
throw new Error(`Invalid RELEASE_TAG '${tag ?? ""}'`);
|
|
||||||
}
|
|
||||||
if (!targetCommitish || !/^[0-9a-f]{40}$/i.test(targetCommitish)) {
|
|
||||||
throw new Error(`Invalid RELEASE_COMMIT_SHA '${targetCommitish ?? ""}'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
let releaseId = null;
|
|
||||||
try {
|
try {
|
||||||
const { data } = await github.rest.repos.getReleaseByTag({
|
const { data } = await github.rest.repos.getReleaseByTag({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
tag,
|
tag,
|
||||||
});
|
});
|
||||||
const { data: updated } = await github.rest.repos.updateRelease({
|
await github.rest.repos.updateRelease({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
release_id: data.id,
|
release_id: data.id,
|
||||||
tag_name: tag,
|
|
||||||
target_commitish: targetCommitish,
|
|
||||||
name,
|
|
||||||
body,
|
body,
|
||||||
|
name,
|
||||||
draft,
|
draft,
|
||||||
prerelease,
|
prerelease,
|
||||||
});
|
});
|
||||||
releaseId = updated.id;
|
return data.id;
|
||||||
core.info(`Updated existing release id=${releaseId} for tag ${tag}`);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.status !== 404) throw e;
|
if (e.status !== 404) throw e;
|
||||||
const { data } = await github.rest.repos.createRelease({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
tag_name: tag,
|
|
||||||
target_commitish: targetCommitish,
|
|
||||||
name,
|
|
||||||
body,
|
|
||||||
draft,
|
|
||||||
prerelease,
|
|
||||||
});
|
|
||||||
releaseId = data.id;
|
|
||||||
core.info(`Created release id=${releaseId} for tag ${tag}`);
|
|
||||||
}
|
}
|
||||||
|
const { data } = await github.rest.repos.createRelease({
|
||||||
if (!releaseId || !Number.isInteger(Number(releaseId))) {
|
|
||||||
throw new Error(`create/update release did not produce numeric id for tag '${tag}'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
core.setOutput("release_id", String(releaseId));
|
|
||||||
- name: validate release id output
|
|
||||||
env:
|
|
||||||
RELEASE_ID: ${{ steps.create_release.outputs.release_id }}
|
|
||||||
TAG: ${{ steps.tag.outputs.value }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
if [ -z "${RELEASE_ID:-}" ]; then
|
|
||||||
echo "::error::create_release did not produce release_id for tag '$TAG'"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if ! printf '%s' "$RELEASE_ID" | grep -qE '^[0-9]+$'; then
|
|
||||||
echo "::error::release_id is not numeric: '$RELEASE_ID'"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
- name: verify release-tag binding
|
|
||||||
uses: actions/github-script@v9
|
|
||||||
env:
|
|
||||||
RELEASE_ID: ${{ steps.create_release.outputs.release_id }}
|
|
||||||
EXPECTED_TAG: ${{ steps.tag.outputs.value }}
|
|
||||||
EXPECTED_SHA: ${{ steps.source-sha.outputs.value }}
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const releaseId = Number(process.env.RELEASE_ID);
|
|
||||||
const expectedTag = process.env.EXPECTED_TAG;
|
|
||||||
const expectedSha = process.env.EXPECTED_SHA;
|
|
||||||
|
|
||||||
const { data: release } = await github.rest.repos.getRelease({
|
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
release_id: releaseId,
|
tag_name: tag,
|
||||||
|
target_commitish: targetCommitish,
|
||||||
|
name,
|
||||||
|
body,
|
||||||
|
draft,
|
||||||
|
prerelease,
|
||||||
});
|
});
|
||||||
|
return data.id;
|
||||||
if (!release.tag_name || release.tag_name.startsWith("untagged-")) {
|
|
||||||
core.setFailed(`release_id=${releaseId} is bound to untagged release '${release.tag_name ?? ""}'`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (release.tag_name !== expectedTag) {
|
|
||||||
core.setFailed(`release_id=${releaseId} has tag '${release.tag_name}', expected '${expectedTag}'`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
||||||
|
|
||||||
let ref = null;
|
|
||||||
let lastRefError = null;
|
|
||||||
for (let attempt = 1; attempt <= 6; attempt++) {
|
|
||||||
try {
|
|
||||||
const resp = await github.rest.git.getRef({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
ref: `tags/${expectedTag}`,
|
|
||||||
});
|
|
||||||
ref = resp.data;
|
|
||||||
break;
|
|
||||||
} catch (e) {
|
|
||||||
if (e.status !== 404) throw e;
|
|
||||||
lastRefError = e;
|
|
||||||
core.warning(`Tag ref '${expectedTag}' is not visible yet (attempt ${attempt}/6); retrying...`);
|
|
||||||
await sleep(1500 * attempt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!ref) {
|
|
||||||
const targetCommitish = (release.target_commitish || "").trim();
|
|
||||||
const isSha = /^[0-9a-f]{40}$/i.test(targetCommitish);
|
|
||||||
if (isSha && targetCommitish.toLowerCase() !== expectedSha.toLowerCase()) {
|
|
||||||
core.setFailed(
|
|
||||||
`release_id=${releaseId} has target_commitish='${targetCommitish}', expected '${expectedSha}', and tag ref is unavailable`
|
|
||||||
);
|
|
||||||
if (lastRefError) core.warning(`Last getRef error: ${lastRefError.message}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
core.warning(
|
|
||||||
`tag ref 'tags/${expectedTag}' not found after retries (release_id=${releaseId}); continuing because release metadata is already bound`
|
|
||||||
);
|
|
||||||
if (lastRefError) core.warning(`Last getRef error: ${lastRefError.message}`);
|
|
||||||
if (isSha) {
|
|
||||||
core.info(`Verified release_id=${releaseId} via target_commitish=${targetCommitish}`);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let resolvedSha = ref.object.sha;
|
|
||||||
if (ref.object.type === "tag") {
|
|
||||||
const { data: tagObj } = await github.rest.git.getTag({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
tag_sha: ref.object.sha,
|
|
||||||
});
|
|
||||||
resolvedSha = tagObj.object.sha;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolvedSha !== expectedSha) {
|
|
||||||
core.setFailed(`tag '${expectedTag}' points to ${resolvedSha}, expected ${expectedSha}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
core.info(`Verified release_id=${releaseId}, tag=${expectedTag}, commit=${resolvedSha}`);
|
|
||||||
|
|
||||||
build-macos-windows:
|
build-macos-windows:
|
||||||
if: ${{ inputs.build_platform_artifacts }}
|
if: ${{ inputs.build_platform_artifacts }}
|
||||||
@@ -336,8 +216,9 @@ jobs:
|
|||||||
mkdir -p ~/private_keys
|
mkdir -p ~/private_keys
|
||||||
echo "${{ secrets.APPLE_API_KEY_B64 }}" | base64 --decode > ~/private_keys/AuthKey.p8
|
echo "${{ secrets.APPLE_API_KEY_B64 }}" | base64 --decode > ~/private_keys/AuthKey.p8
|
||||||
echo "APPLE_API_KEY_PATH=$HOME/private_keys/AuthKey.p8" >> "$GITHUB_ENV"
|
echo "APPLE_API_KEY_PATH=$HOME/private_keys/AuthKey.p8" >> "$GITHUB_ENV"
|
||||||
- name: build app bundles (no release side effects)
|
- uses: tauri-apps/tauri-action@v0
|
||||||
env:
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
VITE_LASTFM_API_KEY: ${{ secrets.VITE_LASTFM_API_KEY }}
|
VITE_LASTFM_API_KEY: ${{ secrets.VITE_LASTFM_API_KEY }}
|
||||||
VITE_LASTFM_API_SECRET: ${{ secrets.VITE_LASTFM_API_SECRET }}
|
VITE_LASTFM_API_SECRET: ${{ secrets.VITE_LASTFM_API_SECRET }}
|
||||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||||
@@ -348,42 +229,9 @@ jobs:
|
|||||||
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
|
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
|
||||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
||||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
||||||
run: npm run tauri:build -- ${{ matrix.settings.args }}
|
with:
|
||||||
- name: upload macOS artifacts
|
releaseId: ${{ needs.create-release.outputs.release_id }}
|
||||||
if: runner.os == 'macOS'
|
args: ${{ matrix.settings.args }}
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
RELEASE_TAG="${{ needs.create-release.outputs.release_tag }}"
|
|
||||||
TARGET_ARG='${{ matrix.settings.args }}'
|
|
||||||
if echo "$TARGET_ARG" | grep -q 'aarch64'; then
|
|
||||||
TARGET="aarch64-apple-darwin"
|
|
||||||
else
|
|
||||||
TARGET="x86_64-apple-darwin"
|
|
||||||
fi
|
|
||||||
mapfile -t FILES < <(find "src-tauri/target/${TARGET}/release/bundle" -type f \
|
|
||||||
\( -name "*.dmg" -o -name "*.app.tar.gz" -o -name "*.sig" \))
|
|
||||||
if [ "${#FILES[@]}" -eq 0 ]; then
|
|
||||||
echo "::error::No macOS artifacts found to upload."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
gh release upload "$RELEASE_TAG" "${FILES[@]}" --clobber
|
|
||||||
- name: upload Windows artifacts
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: |
|
|
||||||
RELEASE_TAG='${{ needs.create-release.outputs.release_tag }}'
|
|
||||||
$files = Get-ChildItem -Path "src-tauri/target/release/bundle" -Recurse -File `
|
|
||||||
| Where-Object { $_.Name -match '\.(exe|msi|msix|zip)$' }
|
|
||||||
if ($files.Count -eq 0) {
|
|
||||||
Write-Error "No Windows artifacts found to upload."
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
foreach ($f in $files) {
|
|
||||||
gh release upload "$RELEASE_TAG" "$($f.FullName)" --clobber
|
|
||||||
}
|
|
||||||
- name: re-sign updater bundle + upload .sig (macOS only)
|
- name: re-sign updater bundle + upload .sig (macOS only)
|
||||||
if: runner.os == 'macOS'
|
if: runner.os == 'macOS'
|
||||||
env:
|
env:
|
||||||
|
|||||||
Reference in New Issue
Block a user