- validate-draft-release.sh 增加「target_sha 必须在 main 历史上」的校验。此前有 write 权限的人可以 建一个指向任意 commit 的 draft release 再 dispatch,那份代码就会被编译并签进正式安装包;唯一的 祖先检查跑在 checkout 之后的不可信工作树里,而负责编译的 TSF job 根本没有这道检查。校验放在 prepare(默认分支上下文)里,所有构建 job 都 needs 它。 - 字体名引用只转义了 `"` 没转义反斜线,以 `\` 结尾的字体名能吃掉闭合引号让后续内容按 CSS 解析。 两处(appearance.ts、shared.ts)都改为先转义转义符。 - voice_input_service.cpp: float 平方先提升到 double - engine-bump-triage.yml 顶层权限从 write 收到 read,写权限下放到 job;runner 与同仓其他 workflow 统一为 ubuntu-24.04 新增 CONTRIBUTING.md,把散在各 AGENTS.md / 组件 README 里的环境要求、构建顺序、打包步骤和提交前 检查串成外部贡献者能照着走完的一条路径,并从 README 首屏链出。
54 lines
2.5 KiB
Bash
Executable File
54 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Check that a manually requested tag names an unpublished draft release pinned to an immutable
|
|
# commit whose version.txt agrees with the tag, then report the commit and version for the build
|
|
# jobs to use. Nothing is built until this passes.
|
|
#
|
|
# Requires GH_TOKEN, GH_REPO, TAG_NAME. Writes target_sha and version to GITHUB_OUTPUT.
|
|
set -euo pipefail
|
|
|
|
if [[ ! "$TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
echo "Tag must use the vMAJOR.MINOR.PATCH format, got '$TAG_NAME'." >&2
|
|
exit 1
|
|
fi
|
|
|
|
release_json=$(gh release view "$TAG_NAME" --json isDraft,targetCommitish)
|
|
|
|
if [[ "$(jq -er .isDraft <<< "$release_json")" != true ]]; then
|
|
echo "Release $TAG_NAME is not an unpublished draft." >&2
|
|
exit 1
|
|
fi
|
|
|
|
target_sha=$(jq -er .targetCommitish <<< "$release_json")
|
|
if [[ ! "$target_sha" =~ ^[0-9a-f]{40}$ ]]; then
|
|
echo "Draft release target must be an immutable full commit SHA, got '$target_sha'." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# The target has to be on main. Without this, anyone able to create a draft release could point it
|
|
# at an arbitrary commit -- a fork's branch, an abandoned branch, a commit that never passed review --
|
|
# and dispatch this workflow to get that code compiled and signed into a published installer.
|
|
#
|
|
# The check belongs here rather than in the build jobs. This runs in the prepare job, which checks
|
|
# out the default branch, so both this script and the answer it gets come from trusted code. The
|
|
# equivalent check in the package job runs after the untrusted commit is already checked out, which
|
|
# means the script performing it is itself supplied by the commit under test; the TSF job, which
|
|
# compiles, had no such check at all. Those remain as defence in depth, not as the gate.
|
|
#
|
|
# compare/main...<sha> reports "behind" when the commit is an ancestor of main and "identical" when
|
|
# it is main's tip. Anything else means it is not in main's history.
|
|
comparison=$(gh api "repos/$GH_REPO/compare/main...$target_sha" --jq .status)
|
|
if [[ "$comparison" != "behind" && "$comparison" != "identical" ]]; then
|
|
echo "Draft release target $target_sha is not in main's history (compare status: $comparison)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
version=$(gh api "repos/$GH_REPO/contents/version.txt?ref=$target_sha" --jq .content | base64 --decode | tr -d '[:space:]')
|
|
if [[ "$TAG_NAME" != "v$version" ]]; then
|
|
echo "Release $TAG_NAME does not match version.txt ($version)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
printf 'target_sha=%s\n' "$target_sha" >> "$GITHUB_OUTPUT"
|
|
printf 'version=%s\n' "$version" >> "$GITHUB_OUTPUT"
|
|
echo "Draft $TAG_NAME is valid: version $version at $target_sha"
|