From ba3ce178c223aec68667c5860f1244f7cc0c91a3 Mon Sep 17 00:00:00 2001 From: Sam Vente Date: Tue, 5 Aug 2025 11:12:42 +0200 Subject: [PATCH 1/4] feat: release_schedule workflow The release_schedule workflow should create the artifacts on this repository so other repositories can access it, and make sure we have a paper trail --- .github/workflows/release_schedule.yaml | 66 +++++++++++++++++++++++++ .gitignore | 3 -- 2 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release_schedule.yaml diff --git a/.github/workflows/release_schedule.yaml b/.github/workflows/release_schedule.yaml new file mode 100644 index 0000000..e575c4a --- /dev/null +++ b/.github/workflows/release_schedule.yaml @@ -0,0 +1,66 @@ +name: Generate release schedule artifacts +on: + schedule: + # At 00:00 on day-of-month 1 in every 3rd month. (i.e. every quarter) + - cron: "0 0 1 */3 *" + # on demand + workflow_dispatch: + +jobs: + create-artifacts: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + # We're going to make a tag that we can we release so we'll need the full history for that + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + - name: Install dependencies + run: | + pip install -r requirements.txt + - name: Run spec_zero_versions.py + run: | + python spec_zero_versions.py + - name: setup git + run : | + # git will complain if we don't do this first + git config user.name "GitHub Actions Bot" + git config user.email "<>" + + - name: determine tag name + id: tag_name + run: | + echo "TAG_NAME=$(date '+%Y-Q%q')" >> "$GITHUB_OUTPUT" + + + - name: create tag + env: + TAG_NAME: ${{ steps.tag_name.outputs.TAG_NAME }} + run: | + git add schedule.md chart.md schedule.json + git commit -m "Update SPEC 0 schedule artifacts" + git tag "$TAG_NAME" + git push origin "$TAG_NAME" + + - name: Publish github release + uses: softprops/action-gh-release@v2 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + generate_release_notes: true + tag_name: ${{ steps.tag_name.outputs.TAG_NAME }} + make_latest: true + files: | + schedule.md + chart.md + schedule.json + + + + diff --git a/.gitignore b/.gitignore index d7a22f5..8f5fd87 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1 @@ .history -chart.md -schedule.md -schedule.json From 30e7fa7c677a42c4a808987270810c1ef4740abc Mon Sep 17 00:00:00 2001 From: Sam Vente Date: Tue, 5 Aug 2025 16:48:59 +0200 Subject: [PATCH 2/4] feat: have action.yml update pixi environments Action should create a PR with updated dependencies. Target branch and tool to be used are configurable. Currently only pixi is supported but it's good to make it possible to add other tools down the line --- action.yaml | 70 ++++++++++++++++++++++++++++++++++++++++---------- update_pixi.sh | 13 ++++++++++ 2 files changed, 69 insertions(+), 14 deletions(-) create mode 100755 update_pixi.sh diff --git a/action.yaml b/action.yaml index ab54c11..742e21d 100644 --- a/action.yaml +++ b/action.yaml @@ -1,26 +1,68 @@ name: "Generate SPEC-0000 Data" description: "Based on the current SPEC 0 schedule, generate a tarball with the latest versions of all packages." +author: Sam Vente +inputs: + target_branch: + description: 'Target branch for the pull request' + required: true + default: 'main' + tool: # for now only pixi, but good to make others possible from the start + description: 'Which tool you use for managing your environment.' + required: true + default: 'pixi' + github_token: + description: 'GitHub token with repo permissions to create pull requests' + required: true + + + runs: using: "composite" steps: - - name: Set up Python - uses: actions/setup-python@v5 + - name: Validate tool input + shell: bash + run: | + if [[ "${{ inputs.tool }}" != "pixi" ]]; then + echo "❌ Invalid tool: '${{ inputs.tool }}'" + echo "Accepted values are: 'pixi'" + exit 1 + fi + - name: Checkout code + uses: actions/checkout@v4 with: - python-version: "3.13" - - name: Install dependencies + fetch-depth: 0 + + - name: Set up Git shell: bash run: | - pip install -r requirements.txt - - name: Run spec_zero_versions.py + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Download schedule artifact + shell: bash + run: gh release download -R "savente93/spec-zero-tools" --pattern schedule.json --clobber + + # make usre pixi is available + - uses: prefix-dev/setup-pixi@v0.8.14 + if: ${{ inputs.tool == 'pixi' }} + name: Setup pixi + with: + pixi-version: v0.49.0 + + - name: Update Pixi dependencies + if: ${{ inputs.tool == 'pixi' }} shell: bash run: | - python spec_zero_versions.py - - name: Upload files as an artifact - uses: actions/upload-artifact@v4 + "${{ github.action_path }}/update_pixi.sh" + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v6 with: - name: spec-zero-versions - path: | - schedule.json - schedule.md - chart.md + token: ${{ inputs.github_token }} + commit-message: "chore: Drop support for unsupported packages conform SPEC 0" + title: "Drop support for unsupported packages conform SPEC 0" + body: "This PR was created automatically" + base: ${{ inputs.target_branch }} + branch: update-spec-0-dependencies-${{ github.run_id }} + diff --git a/update_pixi.sh b/update_pixi.sh new file mode 100755 index 0000000..e7fbe95 --- /dev/null +++ b/update_pixi.sh @@ -0,0 +1,13 @@ +#!/bin/bash + + +for line in $(jq 'map(select(.start_date |fromdateiso8601 |tonumber < now))| sort_by("start_date") | reverse | .[0].packages | to_entries | map(.key + ":" + .value)[]' --raw-output schedule.json); do + + package=$(echo "$line" | cut -d ':' -f 1) + spec_0_version=$(echo "$line" | cut -d ':' -f 2) + + if pixi list -x "^$package" 2> /dev/null | grep "No packages" -q -v; then + echo "Updating $package" + pixi add "$package>=$spec_0_version" + fi +done From 0cdba7a5df28ef6038bd444dbc124238e243b436 Mon Sep 17 00:00:00 2001 From: Sam Vente Date: Tue, 5 Aug 2025 19:26:56 +0200 Subject: [PATCH 3/4] docs: Update README --- action.yaml | 4 +-- readme.md | 75 ++++++++++++++++++++++++----------------------------- 2 files changed, 36 insertions(+), 43 deletions(-) diff --git a/action.yaml b/action.yaml index 742e21d..eb39ff7 100644 --- a/action.yaml +++ b/action.yaml @@ -10,7 +10,7 @@ inputs: description: 'Which tool you use for managing your environment.' required: true default: 'pixi' - github_token: + token: description: 'GitHub token with repo permissions to create pull requests' required: true @@ -59,7 +59,7 @@ runs: - name: Create Pull Request uses: peter-evans/create-pull-request@v6 with: - token: ${{ inputs.github_token }} + token: ${{ inputs.token }} commit-message: "chore: Drop support for unsupported packages conform SPEC 0" title: "Drop support for unsupported packages conform SPEC 0" body: "This PR was created automatically" diff --git a/readme.md b/readme.md index 3918a9e..c8f010a 100644 --- a/readme.md +++ b/readme.md @@ -1,63 +1,56 @@ # SPEC-0 Versions Action -This repository contains a GitHub Action to generate the files required for the SPEC-0 documentation. +This repository contains a Github Action to update python dependencies conform the SPEC 0 support schedule. +It also contains released versions of the schedule in various formats that that action can use to open PRs in your repository. ## Using the action ```yaml -name: Generate spec-zero data +name: Update SPEC 0 dependencies on: - push: - branches: - - main + workflow_dispatch: + schedule: + # At 00:00 on day-of-month 2 in every 3rd month. (i.e. every quarter) + # Releases should happen on the first day of the month in scientific-python/spec-zero-tools + # so allow one day as a buffer to avoid timing issues + - cron: "0 0 2 */3 *" + +permissions: + contents: write + pull-requests: write jobs: - devstats-query: + update: runs-on: ubuntu-latest steps: - uses: scientific-python/spec-zero-tools@main + with: + token: ${{ secrets.GH_PAT }} + target_branch: main + tool: pixi + ``` -The above would produce an artifact named `spec-zero-versions`, the following files: `schedule.yaml`,`schedule.md` and `chart.md`. +Whenever the action is triggered it will open a PR in your repository that will update the dependencies of SPEC 0 to the new lower bound. For this you will have to provide it with a PAT that has write permissions in the `contents` and `pull request` scopes. Please refer to the GitHub documentation for instructions on how to do this [here](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens). To help projects stay compliant with SPEC-0, we provide a `schedule.json` file that can be used by CI systems to determine new version boundaries. -The structure of the file is as follows: - -```json -[ - { - "start_date": "iso8601_timestamp", - "packages": { - "package_name": "version" - } - } -] -``` -All information in the json file is in a string format that should be easy to use. -The date is the first timestamp of the relevant quarter. -Thus a workflow for using this file could be: +Currently the action can take the following inputs: -1. Fetch `schedule.json` -2. Determine maximum date that is smaller than current date -3. Update packages listed with new minimum versions +| Name | Description | Required | +|---------------|-------------------------------------------------------------------------------------------------------------|----------| +| `token` | The token that the action will use to create and update the pull request. See [token](https://github.com/marketplace/actions/create-pull-request#token). | Yes | +| `tool` | Which tool to use for managing your dependencies. Currently `pixi` is the only option. | No | +| `target_branch` | The branch to open a PR against with the updated versions. Defaults to `main`. | No | -You can obtain the new versions you should set by using this `jq` expression: -```sh -jq 'map(select(.start_date |fromdateiso8601 |tonumber < now))| sort_by("start_date") | reverse | .[0].packages ' schedule.json -``` +## Limitations + +This project is still in progress and thus it comes with some limitations we are working on. Hopefully this will be gone by the time you read this, but currently the limitations are: + +- Only `pixi` is supported +- if you have a higher bound than the one listed in SPEC 0 this is overwritten +- higher bounds are deleted instead of maintained. +- dependency groups are not yet supported -If you use a package manager like pixi you could update the dependencies with a bash script like this (untested): - -```sh -curl -Ls -o schedule.json https://raw.githubusercontent.com/scientific-python/specs/main/spec-0000/schedule.json -for line in $(jq 'map(select(.start_date |fromdateiso8601 |tonumber < now))| sort_by("start_date") | reverse | .[0].packages | to_entries | map(.key + ":" + .value)[]' --raw-output schedule.json); do - package=$(echo "$line" | cut -d ':' -f 1) - version=$(echo "$line" | cut -d ':' -f 2) - if pixi list -x "^$package" &>/dev/null| grep "No packages" -q; then - pixi add "$package>=$version"; - fi -done -``` From 2a2b9c04e5059ce668d412a60516f21a9b4c15ff Mon Sep 17 00:00:00 2001 From: Sam Vente Date: Tue, 5 Aug 2025 19:49:04 +0200 Subject: [PATCH 4/4] fix: remove now defunct test_action.yaml --- .github/workflows/release_schedule.yaml | 21 ++++++++------------- action.yaml | 16 ++++++---------- readme.md | 19 ++++++++----------- 3 files changed, 22 insertions(+), 34 deletions(-) diff --git a/.github/workflows/release_schedule.yaml b/.github/workflows/release_schedule.yaml index e575c4a..751bd25 100644 --- a/.github/workflows/release_schedule.yaml +++ b/.github/workflows/release_schedule.yaml @@ -10,13 +10,13 @@ jobs: create-artifacts: runs-on: ubuntu-latest permissions: - contents: write + contents: write steps: - name: Checkout uses: actions/checkout@v4 - with: - # We're going to make a tag that we can we release so we'll need the full history for that - fetch-depth: 0 + with: + # We're going to make a tag that we can we release so we'll need the full history for that + fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v5 with: @@ -28,7 +28,7 @@ jobs: run: | python spec_zero_versions.py - name: setup git - run : | + run: | # git will complain if we don't do this first git config user.name "GitHub Actions Bot" git config user.email "<>" @@ -38,10 +38,9 @@ jobs: run: | echo "TAG_NAME=$(date '+%Y-Q%q')" >> "$GITHUB_OUTPUT" - - name: create tag env: - TAG_NAME: ${{ steps.tag_name.outputs.TAG_NAME }} + TAG_NAME: ${{ steps.tag_name.outputs.TAG_NAME }} run: | git add schedule.md chart.md schedule.json git commit -m "Update SPEC 0 schedule artifacts" @@ -51,16 +50,12 @@ jobs: - name: Publish github release uses: softprops/action-gh-release@v2 env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: generate_release_notes: true - tag_name: ${{ steps.tag_name.outputs.TAG_NAME }} + tag_name: ${{ steps.tag_name.outputs.TAG_NAME }} make_latest: true files: | schedule.md chart.md schedule.json - - - - diff --git a/action.yaml b/action.yaml index eb39ff7..de974b4 100644 --- a/action.yaml +++ b/action.yaml @@ -3,20 +3,17 @@ description: "Based on the current SPEC 0 schedule, generate a tarball with the author: Sam Vente inputs: target_branch: - description: 'Target branch for the pull request' + description: "Target branch for the pull request" required: true - default: 'main' + default: "main" tool: # for now only pixi, but good to make others possible from the start - description: 'Which tool you use for managing your environment.' + description: "Which tool you use for managing your environment." required: true - default: 'pixi' + default: "pixi" token: - description: 'GitHub token with repo permissions to create pull requests' + description: "GitHub token with repo permissions to create pull requests" required: true - - - runs: using: "composite" steps: @@ -43,7 +40,7 @@ runs: shell: bash run: gh release download -R "savente93/spec-zero-tools" --pattern schedule.json --clobber - # make usre pixi is available + # make user pixi is available - uses: prefix-dev/setup-pixi@v0.8.14 if: ${{ inputs.tool == 'pixi' }} name: Setup pixi @@ -65,4 +62,3 @@ runs: body: "This PR was created automatically" base: ${{ inputs.target_branch }} branch: update-spec-0-dependencies-${{ github.run_id }} - diff --git a/readme.md b/readme.md index c8f010a..4313421 100644 --- a/readme.md +++ b/readme.md @@ -25,11 +25,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: scientific-python/spec-zero-tools@main - with: + with: token: ${{ secrets.GH_PAT }} target_branch: main tool: pixi - ``` Whenever the action is triggered it will open a PR in your repository that will update the dependencies of SPEC 0 to the new lower bound. For this you will have to provide it with a PAT that has write permissions in the `contents` and `pull request` scopes. Please refer to the GitHub documentation for instructions on how to do this [here](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens). @@ -38,19 +37,17 @@ To help projects stay compliant with SPEC-0, we provide a `schedule.json` file t Currently the action can take the following inputs: -| Name | Description | Required | -|---------------|-------------------------------------------------------------------------------------------------------------|----------| -| `token` | The token that the action will use to create and update the pull request. See [token](https://github.com/marketplace/actions/create-pull-request#token). | Yes | -| `tool` | Which tool to use for managing your dependencies. Currently `pixi` is the only option. | No | -| `target_branch` | The branch to open a PR against with the updated versions. Defaults to `main`. | No | - +| Name | Description | Required | +| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `token` | The token that the action will use to create and update the pull request. See [token](https://github.com/marketplace/actions/create-pull-request#token). | Yes | +| `tool` | Which tool to use for managing your dependencies. Currently `pixi` is the only option. | No | +| `target_branch` | The branch to open a PR against with the updated versions. Defaults to `main`. | No | ## Limitations -This project is still in progress and thus it comes with some limitations we are working on. Hopefully this will be gone by the time you read this, but currently the limitations are: +This project is still in progress and thus it comes with some limitations we are working on. Hopefully this will be gone by the time you read this, but currently the limitations are: - Only `pixi` is supported - if you have a higher bound than the one listed in SPEC 0 this is overwritten -- higher bounds are deleted instead of maintained. +- higher bounds are deleted instead of maintained. - dependency groups are not yet supported -