diff --git a/.github/scripts/release/README.md b/.github/scripts/release/README.md index 17ca366..9288dc3 100644 --- a/.github/scripts/release/README.md +++ b/.github/scripts/release/README.md @@ -14,13 +14,10 @@ ignored and overwritten. The push uses `--force-with-lease` pinned to the remote sha the run observed. 2. The workflow opens (or updates) a pull request `release` -> `main` with the default `GITHUB_TOKEN`. This needs the repository setting *Actions -> General -> Allow GitHub - Actions to create and approve pull requests*. A PR opened with `GITHUB_TOKEN` - triggers no workflows, so `main-source-guard` would never run on it; the workflow - therefore sets the `only-release-into-main` commit status on the release commit - itself, which satisfies the required check. No PAT is needed; an optional + Actions to create and approve pull requests*. No PAT is needed; an optional `RELEASE_PR_TOKEN` secret is used for the PR step when present. -3. Merging that PR is the only way to change `main`. `main-source-guard.yml` fails - any PR into `main` whose head is not `release`. +3. Merging that PR is the only way to change `main`. The maintainer merges it after checking + that its source branch is `release`; repository settings alone protect `main` (below). 4. On push to `main`, `pages.yml` deploys `docs/guide/` to GitHub Pages. ## What is dropped on release @@ -46,6 +43,7 @@ It refuses to run while `release` is checked out. .github/scripts/release/protect-main.sh # print what would be applied .github/scripts/release/protect-main.sh --apply # apply via gh api (needs admin) -This requires a pull request, blocks force-push and deletion. Classic protection cannot -restrict a PR's source branch, so add the check `only-release-into-main` as required -(the script does; the workflow must have run once first). +The settings (the maintainer's decision, 2026-10-03): a pull request is required with no +approving review, direct push, force-push and deletion are blocked, the branch is not locked, and +only administrators may merge. No workflow checks the source branch; the maintainer does, when +merging the release PR. diff --git a/.github/scripts/release/protect-main.sh b/.github/scripts/release/protect-main.sh index 5d3588f..4bc6514 100755 --- a/.github/scripts/release/protect-main.sh +++ b/.github/scripts/release/protect-main.sh @@ -14,12 +14,13 @@ done [ -n "$REPO" ] || REPO="{owner}/{repo}" # gh expands these placeholders from the current repo BODY='{ - "required_status_checks": {"strict": true, "contexts": ["only-release-into-main"]}, - "enforce_admins": true, + "required_status_checks": null, + "enforce_admins": false, "required_pull_request_reviews": {"required_approving_review_count": 0}, - "restrictions": null, + "restrictions": {"users": [], "teams": [], "apps": []}, "allow_force_pushes": false, - "allow_deletions": false + "allow_deletions": false, + "lock_branch": false }' CMD="gh api --method PUT repos/$REPO/branches/$BRANCH/protection --input -" @@ -29,6 +30,6 @@ if [ "$APPLY" -eq 1 ]; then else echo "[dry run] would run: $CMD" echo "$BODY" - echo "Re-run with --apply to apply. The check 'only-release-into-main' comes from .github/workflows/main-source-guard.yml;" - echo "it must have run once before GitHub accepts it as a required check." + echo "Re-run with --apply to apply (needs admin). 'restrictions' with empty lists means only" + echo "administrators may merge; it is accepted for organisation repositories only." fi diff --git a/.github/workflows/main-source-guard.yml b/.github/workflows/main-source-guard.yml deleted file mode 100644 index 4eb5d20..0000000 --- a/.github/workflows/main-source-guard.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Main source guard - -# Make the job "only-release-into-main" a required status check on main. -on: - pull_request: - branches: [main] - types: [opened, reopened, synchronize, edited] - -permissions: - contents: read - -jobs: - only-release-into-main: - runs-on: ubuntu-latest - steps: - - name: Require head branch "release" - env: - HEAD_REF: ${{ github.head_ref }} - HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} - run: | - if [ "$HEAD_REF" != "release" ] || [ "$HEAD_REPO" != "${{ github.repository }}" ]; then - echo "::error::PRs into main must come from the release branch of this repository (got '$HEAD_REPO:$HEAD_REF')." - exit 1 - fi diff --git a/.github/workflows/release-sync.yml b/.github/workflows/release-sync.yml index cf35f65..8914610 100644 --- a/.github/workflows/release-sync.yml +++ b/.github/workflows/release-sync.yml @@ -10,7 +10,6 @@ on: permissions: contents: write pull-requests: write - statuses: write concurrency: group: release-sync @@ -51,17 +50,3 @@ jobs: else gh pr create --head release --base main --title "$title" --body "$body" fi - - # A PR opened with GITHUB_TOKEN triggers no workflows, so main-source-guard - # never runs on it. Report the guard's verdict for the release commit here: - # this job just generated it from develop, which is exactly what the guard - # requires. A status set with GITHUB_TOKEN satisfies a required check. - - name: Mark release as passing the main source guard - env: - GH_TOKEN: ${{ github.token }} - run: | - set -eu - if ! git rev-parse -q --verify refs/heads/release >/dev/null; then exit 0; fi - gh api "repos/${GITHUB_REPOSITORY}/statuses/$(git rev-parse release)" \ - -f state=success -f context=only-release-into-main \ - -f description="generated from develop ${GITHUB_SHA::7} by release-sync" diff --git a/PROJECT.md b/PROJECT.md index cec7da9..8abdcb3 100644 --- a/PROJECT.md +++ b/PROJECT.md @@ -109,9 +109,9 @@ python3 .github/scripts/check_guide.py # 가이드: HTML 파싱, 링 1. **코루틴 스코프** — 노트북이 import 하는 `DefaultCoroutineScope`·`MainCoroutineScope`. 2. **`pythonx-map.toml` 의 이중 표기** — `pythonx.compose.layout` 과 `pythonx.compose.foundation.layout` 를 둘 다 유지할지. -3. **릴리스·Pages 활성화** — `.github/scripts/release/` 와 `.github/workflows/`(release-sync, main-source-guard, - pages)는 들어와 있다. 실제로 돌려면 원격 푸시, `RELEASE_PR_TOKEN` 시크릿, main 보호 적용이 - 필요하고, 셋 다 메인테이너 승인 사항이다. +3. **릴리스·Pages 활성화** — `.github/scripts/release/` 와 `.github/workflows/`(release-sync, pages)는 + 들어와 있다. main 보호는 저장소 설정만으로 한다(PR 필수, 승인 0, 직접 push·force-push·삭제 + 금지, 머지는 관리자만; #64). 설정 적용과 release→main PR 머지는 메인테이너가 한다. ### 결정됨 (2026-10-03, #60)