mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-10-28 19:06:36 +08:00
fix: 校验采集器草稿绑定提交以支持安全重试
This commit is contained in:
12
.github/workflows/site-adapter-collector.yml
vendored
12
.github/workflows/site-adapter-collector.yml
vendored
@@ -233,10 +233,14 @@ jobs:
|
||||
SOURCE_SHA: ${{ needs.prepare.outputs.source_sha }}
|
||||
run: |
|
||||
if gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" \
|
||||
--json isDraft --jq '.isDraft' > collector-is-draft.txt; then
|
||||
[[ "$(cat collector-is-draft.txt)" == "true" ]]
|
||||
git fetch --no-tags origin "refs/tags/$RELEASE_TAG:refs/tags/$RELEASE_TAG"
|
||||
[[ "$(git rev-parse "$RELEASE_TAG^{commit}")" == "$SOURCE_SHA" ]]
|
||||
--json isDraft,targetCommitish --jq '[.isDraft, .targetCommitish] | @tsv' \
|
||||
> collector-draft-state.txt; then
|
||||
# 草稿尚未发布时标签可能不存在,应核对创建草稿时绑定的源码提交。
|
||||
IFS=$'\t' read -r is_draft draft_source < collector-draft-state.txt
|
||||
if [[ "$is_draft" != "true" || "$draft_source" != "$SOURCE_SHA" ]]; then
|
||||
echo "Refusing to overwrite a published release or a draft from another source commit" >&2
|
||||
exit 1
|
||||
fi
|
||||
gh release upload "$RELEASE_TAG" release-assets/* \
|
||||
--clobber --repo "$GITHUB_REPOSITORY"
|
||||
gh release edit "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" \
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""验证采集器独立版本及发布边界,所有 Git 操作仅使用临时仓库。"""
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
@@ -134,4 +135,59 @@ def test_workflow_separates_releases_and_pins_all_build_sources():
|
||||
publish = jobs["publish"]["steps"][-1]["run"]
|
||||
assert "--target \"$SOURCE_SHA\" --draft" in publish
|
||||
assert "--draft=false --latest=false" in publish
|
||||
assert '"$RELEASE_TAG^{commit}"' in publish
|
||||
assert "--json isDraft,targetCommitish" in publish
|
||||
assert '"$draft_source" != "$SOURCE_SHA"' in publish
|
||||
assert '"$RELEASE_TAG^{commit}"' not in publish
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("draft_flag", "draft_source", "accepted"),
|
||||
[("true", "source-sha", True), ("true", "other-sha", False), ("false", "source-sha", False)],
|
||||
)
|
||||
def test_draft_retry_checks_source_without_requiring_git_tag(
|
||||
tmp_path: Path, draft_flag: str, draft_source: str, accepted: bool,
|
||||
):
|
||||
"""实际运行发布 Shell,确认无标签草稿可重试且拒绝错误源码或正式版本。"""
|
||||
workflow = YAML(typ="safe").load(
|
||||
(PROJECT_ROOT / ".github/workflows/site-adapter-collector.yml").read_text(encoding="utf-8"),
|
||||
)
|
||||
commands = workflow["jobs"]["publish"]["steps"][-1]["run"]
|
||||
binaries = tmp_path / "bin"
|
||||
binaries.mkdir()
|
||||
gh_stub = binaries / "gh"
|
||||
gh_stub.write_text(
|
||||
'#!/bin/bash\n'
|
||||
'if [[ "$1 $2" == "release view" ]]; then\n'
|
||||
' printf "%s\\t%s\\n" "$DRAFT_FLAG" "$DRAFT_SOURCE"\n'
|
||||
'else\n'
|
||||
' printf "%s\\n" "$*" >> "$GH_LOG"\n'
|
||||
'fi\n', encoding="utf-8",
|
||||
)
|
||||
git_stub = binaries / "git"
|
||||
git_stub.write_text("#!/bin/bash\nexit 79\n", encoding="utf-8")
|
||||
for path in (gh_stub, git_stub):
|
||||
path.chmod(0o755)
|
||||
log = tmp_path / "gh.log"
|
||||
environment = {
|
||||
**os.environ,
|
||||
"PATH": f"{binaries}{os.pathsep}{os.environ['PATH']}",
|
||||
"DRAFT_FLAG": draft_flag,
|
||||
"DRAFT_SOURCE": draft_source,
|
||||
"GH_LOG": str(log),
|
||||
"SOURCE_SHA": "source-sha",
|
||||
"RELEASE_TAG": "site-adapter-collector-v1.0.2",
|
||||
"COLLECTOR_VERSION": "1.0.2",
|
||||
"GITHUB_REPOSITORY": "test/collector",
|
||||
}
|
||||
result = subprocess.run(
|
||||
["bash", "-e", "-o", "pipefail", "-c", commands],
|
||||
cwd=tmp_path, env=environment, capture_output=True, text=True, check=False,
|
||||
)
|
||||
if accepted:
|
||||
assert result.returncode == 0, result.stderr
|
||||
calls = log.read_text(encoding="utf-8")
|
||||
assert "release upload site-adapter-collector-v1.0.2" in calls
|
||||
assert "--draft=false --latest=false" in calls
|
||||
else:
|
||||
assert result.returncode != 0
|
||||
assert not log.exists()
|
||||
|
||||
Reference in New Issue
Block a user