diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87c3f121..2d31c504 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -169,11 +169,14 @@ jobs: needs: [ backend, frontend ] permissions: contents: write + pull-requests: write steps: - name: Checkout Code uses: actions/checkout@v4 with: - token: ${{ secrets.GITHUB_TOKEN }} + # PAT required — GITHUB_TOKEN cannot create PRs against a protected + # branch. DOCS_REPO_TOKEN is a classic PAT with repo scope. + token: ${{ secrets.DOCS_REPO_TOKEN }} - name: Setup Node.js uses: actions/setup-node@v4 @@ -226,7 +229,7 @@ jobs: - name: Open / update screenshots PR uses: peter-evans/create-pull-request@v6 with: - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.DOCS_REPO_TOKEN }} branch: chore/refresh-screenshots commit-message: "docs: refresh screenshots" title: "docs: refresh screenshots" @@ -243,23 +246,25 @@ jobs: with: path: sencho - - name: Checkout sencho-docs repo - uses: actions/checkout@v4 - with: - repository: AnsoCode/sencho-docs - token: ${{ secrets.DOCS_REPO_TOKEN }} - path: sencho-docs - # An empty repo (no commits yet) will fail the checkout — handled below - continue-on-error: true - - - name: Initialize sencho-docs if repo is empty + - name: Clone or init sencho-docs + env: + DOCS_TOKEN: ${{ secrets.DOCS_REPO_TOKEN }} run: | - if [ ! -d "sencho-docs/.git" ]; then - echo "sencho-docs has no .git — initializing fresh repo" + # Always start clean so a previous partial/broken checkout can't cause + # "not in a git directory" on subsequent steps. + rm -rf sencho-docs + + REMOTE="https://x-access-token:${DOCS_TOKEN}@github.com/AnsoCode/sencho-docs.git" + + if git clone "${REMOTE}" sencho-docs 2>/dev/null; then + echo "Cloned existing sencho-docs." + else + echo "Clone failed (repo is empty or has no default branch) — initializing." mkdir -p sencho-docs cd sencho-docs - git init -b main - git remote add origin "https://x-access-token:${{ secrets.DOCS_REPO_TOKEN }}@github.com/AnsoCode/sencho-docs.git" + git init + git checkout -b main + git remote add origin "${REMOTE}" fi - name: Copy /docs into sencho-docs root @@ -268,7 +273,6 @@ jobs: - name: Commit and push to sencho-docs working-directory: sencho-docs run: | - git config --global --add safe.directory "$GITHUB_WORKSPACE/sencho-docs" git config user.email "docs-bot@sencho.io" git config user.name "Sencho Docs Bot" git add -A diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dda4198..01ad6dd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- fix(ci): `update-screenshots` — add `pull-requests: write` permission and switch both `actions/checkout` and `peter-evans/create-pull-request` from `GITHUB_TOKEN` to `DOCS_REPO_TOKEN` (PAT with `repo` scope); `GITHUB_TOKEN` is blocked from creating PRs against protected branches +- fix(ci): `sync-docs` — replace `actions/checkout` + init fallback with a single controlled `git clone || git init` bash step; `actions/checkout@v4` leaves a `.git` in a broken state on empty repos, which the `[ ! -d .git ]` guard missed, causing `fatal: not in a git directory` in the commit step; also drop now-unnecessary `--global safe.directory` config + ### Fixed - fix(ci): `update-screenshots` was pushing directly to the protected `develop` branch; replaced the `git push` step with `peter-evans/create-pull-request@v6` which opens/updates a `chore/refresh-screenshots` PR instead - fix(ci): `sync-docs` failed with `fatal: not in a git directory` when `sencho-docs` is empty (no commits); added `continue-on-error: true` on the checkout step plus a fallback `git init -b main` with remote re-add, then pushes with `git push origin HEAD:main` to create the branch on first run