mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
Fix/release untagged guard (#399)
* fix(release): prevent untagged fallback from tauri publish Set explicit github-script output for release_id and validate it before build jobs. This prevents tauri-action from creating untagged releases when release id wiring breaks and keeps assets attached to the intended app-v tag release. * fix(release): add source-only promote mode and harden release binding Add a source_only dispatch option to promote workflows and propagate it into channel publish so maintainers can skip platform builds and verify-nix when needed. Also validate release/tag/commit binding to prevent untagged fallback and ensure source archives stay aligned with the intended app-v tag.
This commit is contained in:
@@ -28,6 +28,11 @@ on:
|
||||
required: false
|
||||
default: true
|
||||
type: boolean
|
||||
build_platform_artifacts:
|
||||
description: "Build and upload macOS/Windows/Linux artifacts + latest.json"
|
||||
required: false
|
||||
default: true
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
@@ -35,7 +40,7 @@ jobs:
|
||||
contents: write
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
release_id: ${{ steps.create-release.outputs.result }}
|
||||
release_id: ${{ steps.create_release.outputs.release_id }}
|
||||
package_version: ${{ steps.get-version.outputs.version }}
|
||||
release_tag: ${{ steps.tag.outputs.value }}
|
||||
source_commit_sha: ${{ steps.source-sha.outputs.value }}
|
||||
@@ -121,7 +126,7 @@ jobs:
|
||||
echo "$BODY" >> "$GITHUB_OUTPUT"
|
||||
echo "$EOF_MARKER" >> "$GITHUB_OUTPUT"
|
||||
- name: create or update release
|
||||
id: create-release
|
||||
id: create_release
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
PACKAGE_VERSION: ${{ steps.get-version.outputs.version }}
|
||||
@@ -139,6 +144,7 @@ jobs:
|
||||
const version = process.env.PACKAGE_VERSION;
|
||||
const targetCommitish = process.env.RELEASE_COMMIT_SHA;
|
||||
const name = `Psysonic v${version}`;
|
||||
let releaseId = null;
|
||||
try {
|
||||
const { data } = await github.rest.repos.getReleaseByTag({
|
||||
owner: context.repo.owner,
|
||||
@@ -154,23 +160,90 @@ jobs:
|
||||
draft,
|
||||
prerelease,
|
||||
});
|
||||
return data.id;
|
||||
releaseId = data.id;
|
||||
core.info(`Updated existing release id=${releaseId} tag=${tag}`);
|
||||
} catch (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} tag=${tag} target_commitish=${targetCommitish}`);
|
||||
}
|
||||
const { data } = await github.rest.repos.createRelease({
|
||||
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@v7
|
||||
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,
|
||||
repo: context.repo.repo,
|
||||
tag_name: tag,
|
||||
target_commitish: targetCommitish,
|
||||
name,
|
||||
body,
|
||||
draft,
|
||||
prerelease,
|
||||
release_id: releaseId,
|
||||
});
|
||||
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 { data: ref } = await github.rest.git.getRef({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
ref: `tags/${expectedTag}`,
|
||||
});
|
||||
|
||||
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:
|
||||
if: ${{ inputs.build_platform_artifacts }}
|
||||
needs: create-release
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -254,6 +327,7 @@ jobs:
|
||||
gh release upload "$RELEASE_TAG" "Psysonic_${ARCH}.app.tar.gz.sig" --clobber
|
||||
|
||||
generate-manifest:
|
||||
if: ${{ inputs.build_platform_artifacts }}
|
||||
needs: [create-release, build-macos-windows]
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
@@ -275,6 +349,7 @@ jobs:
|
||||
gh release upload "$RELEASE_TAG" latest.json --clobber
|
||||
|
||||
build-linux:
|
||||
if: ${{ inputs.build_platform_artifacts }}
|
||||
needs: create-release
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
Reference in New Issue
Block a user