diff --git a/.github/workflows/astro-ci.yml b/.github/workflows/astro-ci.yml new file mode 100644 index 0000000..264a3f5 --- /dev/null +++ b/.github/workflows/astro-ci.yml @@ -0,0 +1,30 @@ +name: CI + +on: + pull_request: + push: + branches: [main, master, dev, work] + +permissions: + contents: read + +jobs: + quality: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Astro + uses: withastro/action@v3 + with: + path: . + node-version: 20 + package-manager: npm + + - name: Type/content check + run: npm run check + + - name: Build site + run: npm run build diff --git a/.github/workflows/astro-pages.yml b/.github/workflows/astro-pages.yml new file mode 100644 index 0000000..280cfe6 --- /dev/null +++ b/.github/workflows/astro-pages.yml @@ -0,0 +1,47 @@ +name: Deploy production site + +on: + push: + branches: [main, master] + workflow_dispatch: + +permissions: + contents: write + +env: + PAGES_BRANCH: gh-pages + +concurrency: + group: deploy-prod + cancel-in-progress: true + +jobs: + deploy: + runs-on: ubuntu-latest + env: + DEPLOY_TARGET: prod + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Astro + uses: withastro/action@v3 + with: + path: . + node-version: 20 + package-manager: npm + + - name: Build production site + run: npm run build + + - name: Add .nojekyll for GitHub Pages + run: touch dist/.nojekyll + + - name: Deploy to pages branch root + uses: JamesIves/github-pages-deploy-action@v4 + with: + branch: ${{ env.PAGES_BRANCH }} + folder: dist + clean: true + clean-exclude: preview diff --git a/.github/workflows/astro-preview.yml b/.github/workflows/astro-preview.yml new file mode 100644 index 0000000..c81743b --- /dev/null +++ b/.github/workflows/astro-preview.yml @@ -0,0 +1,154 @@ +name: Preview on Pull Request + +on: + pull_request: + types: [opened, synchronize, reopened] + workflow_dispatch: + inputs: + pr_number: + description: "Pull request number to deploy preview for" + required: true + type: string + +permissions: + contents: write + pull-requests: write + +concurrency: + group: preview-${{ github.event.pull_request.number || inputs.pr_number }} + cancel-in-progress: true + +env: + PAGES_BRANCH: gh-pages + +jobs: + preview-deploy: + runs-on: ubuntu-latest + env: + PR_NUMBER: ${{ github.event.pull_request.number || inputs.pr_number }} + DEPLOY_TARGET: pr + DEPLOY_PREVIEW_PATH: pr-${{ github.event.pull_request.number || inputs.pr_number }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Ensure gh-pages branch exists + shell: bash + run: | + set -euo pipefail + git fetch --all + if git ls-remote --exit-code --heads origin "$PAGES_BRANCH" >/dev/null 2>&1; then + echo "Branch $PAGES_BRANCH exists" + exit 0 + fi + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git checkout --orphan "$PAGES_BRANCH" + git rm -rf . >/dev/null 2>&1 || true + printf '
Preview bootstrap.
' > index.html + touch .nojekyll + git add index.html .nojekyll + git commit -m "Bootstrap gh-pages for previews" + git push origin "$PAGES_BRANCH" + + - name: Setup Astro + uses: withastro/action@v3 + with: + path: . + node-version: 20 + package-manager: npm + + - name: Build site + run: npm run build + + - name: Add .nojekyll for GitHub Pages + run: touch dist/.nojekyll + + - name: Deploy PR preview to gh-pages + uses: JamesIves/github-pages-deploy-action@v4 + with: + branch: ${{ env.PAGES_BRANCH }} + folder: dist + target-folder: preview/pr-${{ env.PR_NUMBER }} + clean: true + + - name: Compute preview URL + id: preview_url + shell: bash + env: + OWNER: ${{ github.repository_owner }} + REPO: ${{ github.event.repository.name }} + run: | + set -euo pipefail + user_site_repo="${OWNER}.github.io" + if [ "$REPO" = "$user_site_repo" ]; then + url="https://${OWNER}.github.io/preview/pr-${PR_NUMBER}/" + else + url="https://${OWNER}.github.io/${REPO}/preview/pr-${PR_NUMBER}/" + fi + echo "url=$url" >> "$GITHUB_OUTPUT" + + - name: Verify preview URL is reachable + id: verify_preview + continue-on-error: true + shell: bash + env: + PREVIEW_URL: ${{ steps.preview_url.outputs.url }} + run: | + set -euo pipefail + echo "Checking $PREVIEW_URL" + for i in $(seq 1 40); do + code=$(curl -s -L -o /dev/null -w "%{http_code}" "$PREVIEW_URL" || true) + if [ "$code" = "200" ]; then + echo "Preview is live" + exit 0 + fi + echo "Attempt $i/40: HTTP $code, retrying in 15s..." + sleep 15 + done + echo "Preview did not become reachable in time" + exit 1 + + - name: Comment preview URL on PR + if: github.event_name == 'pull_request' && steps.verify_preview.outcome == 'success' + uses: actions/github-script@v7 + env: + PREVIEW_URL: ${{ steps.preview_url.outputs.url }} + with: + script: | + const pr = context.payload.pull_request.number; + const body = [ + '🔍 PR preview is ready.', + '', + `**Open preview:** ${process.env.PREVIEW_URL}` + ].join('\n'); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr, + body + }); + + - name: Comment failure help on PR + if: github.event_name == 'pull_request' && steps.verify_preview.outcome == 'failure' + uses: actions/github-script@v7 + env: + PREVIEW_URL: ${{ steps.preview_url.outputs.url }} + with: + script: | + const pr = context.payload.pull_request.number; + const body = [ + '⚠️ PR preview was deployed but the URL was not reachable yet.', + '', + `Try opening: ${process.env.PREVIEW_URL}`, + '', + 'If it still does not load, wait 2-5 minutes and re-run the `Preview on Pull Request` workflow.' + ].join('\n'); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr, + body + }); diff --git a/.github/workflows/bootstrap-pages-branch.yml b/.github/workflows/bootstrap-pages-branch.yml new file mode 100644 index 0000000..bd2150a --- /dev/null +++ b/.github/workflows/bootstrap-pages-branch.yml @@ -0,0 +1,50 @@ +name: Bootstrap gh-pages branch + +on: + workflow_dispatch: + +permissions: + contents: write + +jobs: + bootstrap: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create gh-pages branch if missing + shell: bash + run: | + set -euo pipefail + git fetch --all + + if git ls-remote --exit-code --heads origin gh-pages >/dev/null 2>&1; then + echo "gh-pages branch already exists; nothing to do." + exit 0 + fi + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git checkout --orphan gh-pages + git rm -rf . >/dev/null 2>&1 || true + + cat > index.html <<'HTML' + + + + + +GitHub Pages bootstrap branch created. Deploy workflows will replace this content.
+ + + HTML + + touch .nojekyll + git add index.html .nojekyll + git commit -m "Bootstrap gh-pages branch" + git push origin gh-pages diff --git a/.github/workflows/hugo.yml b/.github/workflows/hugo.yml deleted file mode 100644 index a8cf471..0000000 --- a/.github/workflows/hugo.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Sample workflow for building and deploying a Hugo site to GitHub Pages -name: Deploy Hugo site to Pages - -on: - # Runs on pushes targeting the default branch - push: - branches: ["main"] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -# Default to bash -defaults: - run: - shell: bash - -jobs: - # Build job - build: - runs-on: ubuntu-latest - env: - HUGO_VERSION: 0.128.0 - steps: - - name: Install Hugo CLI - run: | - wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ - && sudo dpkg -i ${{ runner.temp }}/hugo.deb - - name: Install Dart Sass - run: sudo snap install dart-sass - - name: Checkout - uses: actions/checkout@v4 - with: - submodules: recursive - - name: Setup Pages - id: pages - uses: actions/configure-pages@v5 - - name: Install Node.js dependencies - run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true" - - name: Build with Hugo - env: - HUGO_CACHEDIR: ${{ runner.temp }}/hugo_cache - HUGO_ENVIRONMENT: production - run: | - hugo \ - --minify \ - --baseURL "${{ steps.pages.outputs.base_url }}/" - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: ./public - - # Deployment job - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/MIGRATION_NOTES.md b/MIGRATION_NOTES.md new file mode 100644 index 0000000..c63b4a6 --- /dev/null +++ b/MIGRATION_NOTES.md @@ -0,0 +1,32 @@ +# Hugo -> Astro migration notes + +## Status + +This branch now includes a real Astro project (`package.json`, `astro.config.mjs`, `src/`) and Astro CI/deploy workflows. + +## PR preview URLs (before merge) + +- Every PR build deploys to `gh-pages` under `preview/pr-+ Minimal Astro theme for technical writing. Structured lists, calm typography, optional TOC, and + dark mode included. +
+{note.data.description}
+