diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml index 6e447db95..f6b07c21a 100644 --- a/.github/workflows/linkcheck.yml +++ b/.github/workflows/linkcheck.yml @@ -9,26 +9,43 @@ jobs: name: Link Checking runs-on: "ubuntu-latest" permissions: + contents: read # read latest release assets via gh api issues: write # required for peter-evans/create-issue-from-file steps: - # Checkout the live site (html) - - name: Checkout - uses: actions/checkout@v7 - with: - ref: gh-pages + # Download the live site (html) from the latest release archive + # (permanent, not subject to artifact expiry) instead of the gh-pages + # branch, which no longer exists after the artifact-based Pages migration. + - name: Get latest release asset URL + id: release + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + ASSET_URL=$(gh api repos/${{ github.repository }}/releases/latest \ + --jq '[.assets[] | select(.name | endswith(".tar.gz")) | .browser_download_url] | first // ""') + if [ -z "$ASSET_URL" ]; then + echo "::error::No .tar.gz asset found on the latest release" + exit 1 + fi + echo "asset-url=$ASSET_URL" >> "$GITHUB_OUTPUT" + - name: Download and extract release HTML + run: | + set -euo pipefail + mkdir -p _site + curl -fsSL "${{ steps.release.outputs.asset-url }}" | tar -xzf - -C _site - name: Link Checker id: lychee uses: lycheeverse/lychee-action@v2 with: fail: false # --root-dir resolves root-relative links (e.g. /_notebooks/*.ipynb, - # /_pdf/quantecon-python.pdf) against the gh-pages checkout so they are + # /_pdf/quantecon-python.pdf) against the extracted site so they are # not reported as errors. See QuantEcon/lecture-python.myst#906. # # The flags below clear the residual false positives reported in # QuantEcon/lecture-python.myst#933. Configuration is kept inline (rather - # than a lychee.toml) because lychee runs against the gh-pages checkout, - # which does not contain repo-root config files. + # than a lychee.toml) because lychee runs against the extracted release + # archive in _site, which does not contain repo-root config files. # --accept 202 IEEE Xplore returns "202 Accepted" (anti-bot) for # valid links, e.g. doi.org/10.1109/TAC.1977.1101561 # --exclude-path ... genindex / search / prf-prf are auto-generated @@ -42,13 +59,13 @@ jobs: # login/paywall loop (exceeds max-redirects); the # citation itself is valid. args: >- - --root-dir ${{ github.workspace }} + --root-dir ${{ github.workspace }}/_site --accept 200,202,403,503 --exclude-path 'genindex\.html$' --exclude-path 'search\.html$' --exclude-path 'prf-prf\.html$' --exclude '10\.3905/jod\.2012\.20\.1\.038' - *.html + _site/*.html - name: Create Issue From File if: steps.lychee.outputs.exit_code != 0 uses: peter-evans/create-issue-from-file@v6 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 465aecf27..853157949 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,10 +3,26 @@ on: push: tags: - 'publish*' + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: write # write: upload release assets (html archive, checksum, manifest) + actions: read # dawidd6/action-download-artifact reads the cache.yml build artifact + pages: write + id-token: write # required for OIDC-based Pages deployment + +# Allow only one concurrent deployment; don't cancel an in-flight deploy +concurrency: + group: "pages" + cancel-in-progress: false + jobs: publish: if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') runs-on: "runs-on=${{ github.run_id }}/family=g4dn.2xlarge/image=quantecon_ubuntu2404/volume=80gb/spot=false" + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page-url }} steps: - name: Checkout uses: actions/checkout@v7 @@ -92,38 +108,15 @@ jobs: with: name: execution-reports-html path: _build/html/reports - # Create HTML archive for release assets - - name: Create HTML archive - shell: bash -l {0} - run: | - tar -czf lecture-python-html-${{ github.ref_name }}.tar.gz -C _build/html . - sha256sum lecture-python-html-${{ github.ref_name }}.tar.gz > html-checksum.txt - - # Create metadata manifest - cat > html-manifest.json << EOF - { - "tag": "${{ github.ref_name }}", - "commit": "${{ github.sha }}", - "timestamp": "$(date -Iseconds)", - "size_mb": $(du -sm _build/html | cut -f1), - "file_count": $(find _build/html -type f | wc -l) - } - EOF - - name: Upload archives to release - uses: softprops/action-gh-release@v3 - with: - files: | - lecture-python-html-${{ github.ref_name }}.tar.gz - html-checksum.txt - html-manifest.json - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Deploy website to gh-pages - uses: peaceiris/actions-gh-pages@v4 + - name: Deploy to GitHub Pages + id: deployment + uses: quantecon/actions/publish-gh-pages@v0.6.0 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: _build/html/ + build-dir: _build/html cname: python.quantecon.org + create-release-assets: 'true' + asset-name: 'lecture-python-html' + github-token: ${{ secrets.GITHUB_TOKEN }} - name: Prepare lecture-python.notebooks sync shell: bash -l {0} run: |