diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..0cd7497 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,23 @@ +# Dependabot: keep the workflow pins on current majors, so hand-written +# workflows cannot drift back onto end-of-life runtimes unnoticed. +# +# Two groups, the form QuantEcon/actions uses, so updates land as at most two +# PRs a week: "github-actions" for minor/patch (low risk, merge together) and +# "github-actions-major" for majors (read the release notes first). +# `directory: /` covers .github/workflows/. +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 10 + commit-message: + prefix: "⬆️" + groups: + github-actions: + patterns: ["*"] + update-types: [minor, patch] + github-actions-major: + patterns: ["*"] + update-types: [major] diff --git a/.github/workflows/audit-dashboard.yml b/.github/workflows/audit-dashboard.yml index f4879e6..34dae6d 100644 --- a/.github/workflows/audit-dashboard.yml +++ b/.github/workflows/audit-dashboard.yml @@ -38,7 +38,7 @@ jobs: outputs: warnings: ${{ steps.warnings.outputs.text }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: # Nothing under `lectures/` may be an LFS object (.gitattributes # scopes LFS to `sources/**`), and this job publishes `lectures/` to @@ -49,7 +49,7 @@ jobs: # as pointer text everywhere else. It also keeps `sources/` — a 99 MiB # LFS object — off every run of this workflow. lfs: false - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v7 with: python-version: "3.12" - run: pip install pyyaml @@ -85,7 +85,7 @@ jobs: cp -r site/. _site/ cp -r lectures _site/lectures cp audit.json _site/audit.json - - uses: actions/upload-pages-artifact@v3 + - uses: actions/upload-pages-artifact@v5 with: path: _site @@ -100,11 +100,11 @@ jobs: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - - uses: actions/configure-pages@v5 + - uses: actions/configure-pages@v6 with: enablement: true - id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@v5 # The strict build is this repo's drift alarm for 8 upstream lecture repos, # and the weekly schedule fires when nobody is watching. It worked exactly as diff --git a/.github/workflows/consumed-file-check.yml b/.github/workflows/consumed-file-check.yml index 977babd..6a364b0 100644 --- a/.github/workflows/consumed-file-check.yml +++ b/.github/workflows/consumed-file-check.yml @@ -15,7 +15,7 @@ jobs: consumed-files: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: # `lfs: false` is the assertion, not a saving. A manifest records the # sha256 of the real bytes, so if a `lectures/` file is ever @@ -34,7 +34,7 @@ jobs: # by mistake arrives as real bytes, hashes to something the README # does not record, and goes red. lfs: false - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v7 with: python-version: "3.12" - run: pip install pyyaml diff --git a/.github/workflows/refresh-snapshots.yml b/.github/workflows/refresh-snapshots.yml index 94cccfd..7920602 100644 --- a/.github/workflows/refresh-snapshots.yml +++ b/.github/workflows/refresh-snapshots.yml @@ -58,10 +58,10 @@ jobs: all: ${{ steps.plan.outputs.all }} due: ${{ steps.plan.outputs.due }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: lfs: false - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v7 with: python-version: "3.12" - run: pip install pyyaml @@ -99,10 +99,10 @@ jobs: # A matrix cannot expose one output per leg, so a failing leg leaves its # failure.json + log as an artifact and the notify job reads those. steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: lfs: false - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v7 with: python-version: "3.12" - run: pip install -r requirements.txt @@ -130,7 +130,7 @@ jobs: exit "$code" - name: Keep the failure for the notifier if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: canary-failure-${{ matrix.snapshot.stem }} path: | @@ -145,7 +145,7 @@ jobs: permissions: issues: write steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: pattern: canary-failure-* path: failures @@ -161,8 +161,13 @@ jobs: { echo "The weekly sources-alive canary failed. Nothing was written: every consumer keeps reading the last-good snapshot, so no lecture is affected — this is the alarm moving from the lecture repos' CI to here, doing its job." echo - for dir in failures/*/; do - [ -f "$dir/failure.json" ] || continue + # download-artifact v5+ unpacks a lone artifact straight into + # failures/ (one leg failed, the usual case) and several into + # failures//, so find each failure.json wherever it landed + # and read builder.log beside it. If nothing was uploaded (plan + # failed, or a leg failed before its builder ran) there is no + # failures/ and the loop finds nothing, as the old glob did. + while IFS= read -r dir; do dataset=$(jq -r .dataset "$dir/failure.json") builder=$(jq -r .builder "$dir/failure.json") kind=$(jq -r .kind "$dir/failure.json") @@ -179,7 +184,7 @@ jobs: tail -n 15 "$dir/builder.log" echo '```' echo - done + done < <(find failures -type f -name failure.json -exec dirname {} \; 2>/dev/null | sort) echo "Run: $RUN_URL" echo echo "_Posted automatically. Later failures comment here rather than opening new issues, so close this once the canary is green._" @@ -208,13 +213,13 @@ jobs: snapshot: ${{ fromJson(needs.plan.outputs.due) }} name: refresh (${{ matrix.snapshot.dataset }}) steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: lfs: false # The PAT, when present, is what lets the PR trigger `consumed-files` # (see the header). `persist-credentials` keeps it for the push. token: ${{ secrets.QUANTECON_SERVICES_PAT || github.token }} - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v7 with: python-version: "3.12" - run: pip install -r requirements.txt diff --git a/.github/workflows/validate-datasets.yml b/.github/workflows/validate-datasets.yml index 9338967..413cec2 100644 --- a/.github/workflows/validate-datasets.yml +++ b/.github/workflows/validate-datasets.yml @@ -42,10 +42,10 @@ jobs: pandas: ["2.3.3", "3.0.5"] name: validate (pandas ${{ matrix.pandas }}) steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: lfs: false # lectures/ is plain git; a pointer here should fail (see consumed-file-check.yml) - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v7 with: python-version: "3.12" # wbgapi: builders/business_cycle.py imports it at module level, and the