diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index f6af195e..2d0848b1 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -150,6 +150,7 @@ jobs: repository: ${{ github.repository }} ref: ${{ needs.prepare.outputs.branch }} token: ${{ env.REPO_READONLY_PAT }} + persist-credentials: false - name: Set up QEMU uses: docker/setup-qemu-action@v3 diff --git a/.github/workflows/build-executable.yml b/.github/workflows/build-executable.yml index ae671cf1..f2ad3f17 100644 --- a/.github/workflows/build-executable.yml +++ b/.github/workflows/build-executable.yml @@ -72,6 +72,7 @@ jobs: repository: ${{ env.githubRepository }} ref: ${{ github.ref_name }} token: ${{ env.REPO_READONLY_PAT }} + persist-credentials: false - name: Setup dotnet uses: actions/setup-dotnet@v5 diff --git a/.github/workflows/build-frontend.yml b/.github/workflows/build-frontend.yml index 6c720b5d..547ab501 100644 --- a/.github/workflows/build-frontend.yml +++ b/.github/workflows/build-frontend.yml @@ -30,6 +30,7 @@ jobs: repository: ${{ github.repository }} ref: ${{ inputs.ref || github.ref_name }} token: ${{ env.REPO_READONLY_PAT }} + persist-credentials: false - name: Setup Node.js uses: actions/setup-node@v4 diff --git a/.github/workflows/build-macos-installer.yml b/.github/workflows/build-macos-installer.yml index 1a863427..01d42e68 100644 --- a/.github/workflows/build-macos-installer.yml +++ b/.github/workflows/build-macos-installer.yml @@ -76,6 +76,7 @@ jobs: ref: ${{ github.ref_name }} token: ${{ env.REPO_READONLY_PAT }} fetch-depth: 0 + persist-credentials: false - name: Download frontend artifact uses: actions/download-artifact@v4 diff --git a/.github/workflows/build-windows-installer.yml b/.github/workflows/build-windows-installer.yml index 61eea5c0..6b1fcbf4 100644 --- a/.github/workflows/build-windows-installer.yml +++ b/.github/workflows/build-windows-installer.yml @@ -65,6 +65,7 @@ jobs: repository: ${{ env.githubRepository }} ref: ${{ inputs.ref || github.ref_name }} token: ${{ env.REPO_READONLY_PAT }} + persist-credentials: false - name: Download frontend artifact uses: actions/download-artifact@v4 diff --git a/.github/workflows/cloudflare-pages-blocklists.yml b/.github/workflows/cloudflare-pages-blocklists.yml index e1293c1d..7a6c27de 100644 --- a/.github/workflows/cloudflare-pages-blocklists.yml +++ b/.github/workflows/cloudflare-pages-blocklists.yml @@ -20,6 +20,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + persist-credentials: false - name: Create directory for static files run: | diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index bbe99c03..0f95332d 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -20,6 +20,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + persist-credentials: false - name: Dependency Review uses: actions/dependency-review-action@v4 diff --git a/.github/workflows/docs-preview-cleanup.yml b/.github/workflows/docs-preview-cleanup.yml new file mode 100644 index 00000000..5926502f --- /dev/null +++ b/.github/workflows/docs-preview-cleanup.yml @@ -0,0 +1,53 @@ +name: Docs Preview Cleanup + +on: + pull_request: + types: [closed] + paths: + - 'docs/**' + +permissions: + contents: read + +jobs: + cleanup: + runs-on: ubuntu-latest + # Skip fork PRs + if: github.event.pull_request.head.repo.full_name == github.repository + env: + CF_API_TOKEN: ${{ secrets.CLOUDFLARE_PAGES_TOKEN }} + PROJECT: cleanuparr-docs + BRANCH: pull-${{ github.event.pull_request.number }} + steps: + - name: Delete preview deployments for this PR + run: | + set -euo pipefail + api="https://api.cloudflare.com/client/v4" + auth="Authorization: Bearer $CF_API_TOKEN" + + account_id=$(curl -fsS -H "$auth" "$api/accounts" | jq -r '.result[0].id') + echo "Account $account_id, tearing down branch $BRANCH" + + ids="" + page=1 + while :; do + resp=$(curl -fsS -H "$auth" \ + "$api/accounts/$account_id/pages/projects/$PROJECT/deployments?page=$page&per_page=25") + count=$(echo "$resp" | jq '.result | length') + [ "$count" -eq 0 ] && break + + page_ids=$(echo "$resp" | jq -r --arg b "$BRANCH" \ + '.result[] | select(.deployment_trigger.metadata.branch == $b) | .id') + ids="$ids $page_ids" + page=$((page + 1)) + done + + deleted=0 + for id in $ids; do + echo "Deleting deployment $id" + curl -fsS -X DELETE -H "$auth" \ + "$api/accounts/$account_id/pages/projects/$PROJECT/deployments/$id?force=true" >/dev/null + deleted=$((deleted + 1)) + done + + echo "Deleted $deleted deployment(s) for $BRANCH" diff --git a/.github/workflows/docs-preview.yml b/.github/workflows/docs-preview.yml new file mode 100644 index 00000000..15df6475 --- /dev/null +++ b/.github/workflows/docs-preview.yml @@ -0,0 +1,84 @@ +name: Docs Preview + +on: + pull_request: + paths: + - 'docs/**' + +concurrency: + group: docs-preview-${{ github.event.pull_request.number }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: write + +jobs: + preview: + runs-on: ubuntu-latest + # Skip fork PRs + if: github.event.pull_request.head.repo.full_name == github.repository + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 26.x + cache: yarn + cache-dependency-path: docs/yarn.lock + + - name: Install dependencies + working-directory: docs + run: yarn install --frozen-lockfile + + - name: Build Docusaurus + working-directory: docs + run: yarn build + + - name: Deploy preview to Cloudflare Pages + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_PAGES_TOKEN }} + workingDirectory: docs + command: pages deploy build --project-name=cleanuparr-docs --branch=pull-${{ github.event.pull_request.number }} + + - name: Comment preview URL + uses: actions/github-script@v7 + with: + script: | + const url = `https://pull-${context.issue.number}.cleanuparr-docs.pages.dev`; + const marker = ''; + const body = [ + marker, + `Docs preview for \`${context.payload.pull_request.head.ref}\` (\`${context.payload.pull_request.head.sha.substring(0, 7)}\`):`, + ``, + `${url}/docs` + ].join('\n'); + + const comments = await github.paginate(github.rest.issues.listComments, { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + per_page: 100 + }); + const existing = comments.find(c => c.body.includes(marker)); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body + }); + } diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c75103f3..a29e43c9 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -10,10 +10,7 @@ permissions: id-token: write jobs: - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} + publish: runs-on: ubuntu-latest steps: - name: Checkout @@ -21,6 +18,7 @@ jobs: with: fetch-depth: 0 ref: main + persist-credentials: false - name: Set up Node.js uses: actions/setup-node@v4 @@ -37,12 +35,39 @@ jobs: working-directory: docs run: yarn build + - name: Publish to org site + uses: peaceiris/actions-gh-pages@v4 + with: + personal_token: ${{ secrets.DOCS_DEPLOY_TOKEN }} + external_repository: Cleanuparr/Cleanuparr.github.io + publish_branch: gh-pages + publish_dir: docs/build + + redirect: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Build redirect stub + run: | + mkdir redirect + cat > redirect/404.html <<'EOF' + + + + EOF + cp redirect/404.html redirect/index.html + - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: - path: docs/build + path: redirect retention-days: 1 - - name: Deploy to GitHub Pages + - name: Deploy redirect to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 \ No newline at end of file + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 812e3b20..edd8f92d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -43,6 +43,8 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 timeout-minutes: 1 + with: + persist-credentials: false - name: Get vault secrets uses: hashicorp/vault-action@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 10a024c3..e3128800 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -47,6 +47,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + persist-credentials: false - name: Get version info id: version diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d44f0696..3bb41dec 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,6 +27,8 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 timeout-minutes: 1 + with: + persist-credentials: false - name: Setup .NET uses: actions/setup-dotnet@v5 diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 39a875a2..7090a124 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -8,10 +8,10 @@ const config: Config = { favicon: 'img/favicon.ico', url: 'https://cleanuparr.github.io', - baseUrl: '/Cleanuparr/', + baseUrl: '/', organizationName: 'Cleanuparr', - projectName: 'Cleanuparr', + projectName: 'Cleanuparr.github.io', onBrokenLinks: 'throw',