Skip to content

Commit 49de828

Browse files
authored
Merge pull request #29 from scientific-python/fixes
Lets see if i can fix anything
2 parents 4a1b283 + 9facfd2 commit 49de828

10 files changed

Lines changed: 247 additions & 93 deletions

File tree

.github/workflows/test_action.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
name: Run action on test file in repo
2121
steps:
2222
- name: Checkout
23-
uses: actions/checkout@v6
23+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2424
- name: Generate version data using local action
2525
uses: ./
2626
with:

.github/workflows/test_bench.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- name: Checkout
18-
uses: actions/checkout@v6
19-
- uses: prefix-dev/setup-pixi@v0.9.5
18+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
19+
- uses: prefix-dev/setup-pixi@5185adfbffb4bd703da3010310260805d89ebb11 # v0.9.6
2020
with:
21-
pixi-version: "v0.49.0"
21+
pixi-version: "v0.69.0"
2222
- run: |
2323
pixi run test
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Update SPEC 0 schedule
2+
3+
on:
4+
schedule:
5+
- cron: "0 0 1 1,4,7,10 *" # Quarterly: 1st Jan, Apr, Jul, Oct
6+
workflow_dispatch:
7+
8+
jobs:
9+
update-schedule:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: write
13+
steps:
14+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
15+
- uses: prefix-dev/setup-pixi@5185adfbffb4bd703da3010310260805d89ebb11 # v0.9.6
16+
with:
17+
pixi-version: "v0.69.0"
18+
- name: Generate schedule files
19+
run: pixi run generate-schedules
20+
- name: Publish schedule as release asset
21+
env:
22+
GH_TOKEN: ${{ github.token }}
23+
run: |
24+
QUARTER="Q$(( ($(date +%-m) - 1) / 3 + 1 ))"
25+
YEAR=$(date +%Y)
26+
TAG="schedule-${YEAR}-${QUARTER}"
27+
gh release create "$TAG" schedule.json schedule.md \
28+
--title "SPEC 0 Schedule ${YEAR}-${QUARTER}" \
29+
--notes "Quarterly auto-generated SPEC 0 support schedule. Downloaded automatically by spec0-action."

.pre-commit-config.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b # frozen: v5.0.0
3+
rev: v6.0.0
44
hooks:
55
- id: check-added-large-files
66
- id: check-ast
@@ -15,19 +15,19 @@ repos:
1515
- id: mixed-line-ending
1616
- id: trailing-whitespace
1717
- repo: https://github.com/rbubley/mirrors-prettier
18-
rev: 787fb9f542b140ba0b2aced38e6a3e68021647a3 # frozen: v3.5.3
18+
rev: v3.8.3
1919
hooks:
2020
- id: prettier
2121
files: \.(css|html|md|yml|yaml|gql)
2222
args: [--prose-wrap=preserve]
2323
- repo: https://github.com/astral-sh/ruff-pre-commit
24-
rev: 971923581912ef60a6b70dbf0c3e9a39563c9d47 # frozen: v0.11.4
24+
rev: v0.15.14
2525
hooks:
26-
- id: ruff
26+
- id: ruff-check
2727
args: ["--fix", "--show-fixes", "--exit-non-zero-on-fix"]
2828
- id: ruff-format
2929
- repo: https://github.com/codespell-project/codespell
30-
rev: "63c8f8312b7559622c0d82815639671ae42132ac" # frozen: v2.4.1
30+
rev: "v2.4.2"
3131
hooks:
3232
- id: codespell
3333

action.yaml

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
name: "Update SPEC 0 dependencies"
33
description: "Update the lower bounds of Python dependencies covered by the Scientific Python SPEC 0 support schedule"
44
author: Scientific Python Developers
5-
65
inputs:
76
target_branch:
87
description: "Target branch for the pull request"
@@ -15,7 +14,7 @@ inputs:
1514
create_pr:
1615
description: "Whether the action should open a PR or not. Set to false for dry-run/testing."
1716
required: true
18-
default: true
17+
default: "true"
1918
commit_msg:
2019
description: "Commit message for the commit to update the versions. by default 'Drop support for unsupported packages conform SPEC 0'. has no effect if `create_pr` is set to false"
2120
required: false
@@ -25,39 +24,53 @@ inputs:
2524
required: false
2625
default: "chore: Drop support for unsupported packages conform SPEC 0"
2726
schedule_path:
28-
description: "Path to the schedule.json file relative to the project root. If missing, it will be downloaded from the latest release of savente93/SPEC0-schedule"
29-
default: "schedule.json"
27+
description: "Path to the schedule.json file relative to the project root. If not provided, the schedule bundled with the action is used."
28+
required: false
29+
default: ""
3030
token:
31-
description: "GitHub token with repo permissions to create pull requests"
32-
required: true
33-
31+
description: "GitHub token with pull-requests write permission to create pull requests. Defaults to the built-in GITHUB_TOKEN."
32+
required: false
33+
update_all:
34+
description: "If set, also update all non-SPEC0 dependencies to versions released within the last N years (e.g., 2)."
35+
required: false
36+
default: ""
3437
runs:
3538
using: "composite"
3639
steps:
3740
- name: Checkout code
38-
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
41+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3942
- name: Set up Git
4043
shell: bash
4144
run: |
4245
git config user.name "Scientific Python [bot]"
4346
git config user.email "scientific-python@users.noreply.github.com"
44-
- uses: prefix-dev/setup-pixi@1b2de7f3351f171c8b4dfeb558c639cb58ed4ec0 # v0.9.5
47+
- uses: prefix-dev/setup-pixi@5185adfbffb4bd703da3010310260805d89ebb11 # v0.9.6
4548
name: Setup Pixi
4649
with:
47-
pixi-version: v0.49.0
50+
pixi-version: v0.69.0
4851
manifest-path: ${{ github.action_path }}/pyproject.toml
49-
- name: Fetch Schedule from release
52+
- name: Fetch schedule from release
53+
if: ${{ inputs.schedule_path == '' }}
5054
uses: robinraju/release-downloader@28fc21f50d76778e7023361aa1f863e717d3d56f # v1.13
5155
with:
52-
repository: "savente93/SPEC0-schedule"
56+
repository: "scientific-python/spec0-action"
5357
latest: true
5458
fileName: "schedule.json"
5559
- name: Run update script
5660
shell: bash
5761
run: |
5862
set -e
59-
echo "Updating ${{ inputs.project_file_name }} using schedule ${{ inputs.schedule_path }}"
60-
pixi run --manifest-path ${{ github.action_path }}/pyproject.toml update-dependencies "${{ github.workspace }}/${{ inputs.project_file_name }}" "${{ github.workspace }}/${{ inputs.schedule_path }}"
63+
if [ -n "${{ inputs.schedule_path }}" ]; then
64+
SCHEDULE_PATH="${{ github.workspace }}/${{ inputs.schedule_path }}"
65+
else
66+
SCHEDULE_PATH="${{ github.workspace }}/schedule.json"
67+
fi
68+
echo "Updating ${{ inputs.project_file_name }} using schedule $SCHEDULE_PATH"
69+
UPDATE_ALL_FLAG=""
70+
if [ -n "${{ inputs.update_all }}" ]; then
71+
UPDATE_ALL_FLAG="--update-all ${{ inputs.update_all }}"
72+
fi
73+
pixi run --manifest-path ${{ github.action_path }}/pyproject.toml update-dependencies "${{ github.workspace }}/${{ inputs.project_file_name }}" "$SCHEDULE_PATH" $UPDATE_ALL_FLAG
6174
- name: Changes
6275
id: changes
6376
shell: bash
@@ -73,7 +86,7 @@ runs:
7386
if: ${{ fromJSON(inputs.create_pr) && fromJSON(steps.changes.outputs.changes_detected) }}
7487
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
7588
with:
76-
token: ${{ inputs.token }}
89+
token: ${{ inputs.token || github.token }}
7790
commit-message: ${{ inputs.commit_msg }}
7891
title: ${{ inputs.pr_title }}
7992
body: "This PR was created automatically"

readme.md

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,21 @@
11
# SPEC 0 Versions Action
22

3-
This repository contains a Github Action to update Python dependencies in your `pyproject.toml` such that they conform to the SPEC 0 support schedule.
4-
[You can find this schedule here.](https://scientific-python.org/specs/spec-0000/)
3+
A GitHub Action that updates the lower bounds of Python dependencies in `pyproject.toml` to conform to the [SPEC 0 support schedule](https://scientific-python.org/specs/spec-0000/).
54

65
## Using the action
76

87
### Example workflow
98

10-
To use the action you can copy the yaml below, and paste it into `.github/workflows/update-spec0.yaml`.
11-
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.
12-
For this you will have to provide it with a PAT that has write permissions in the `contents` and `pull request` scopes.
13-
[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)
9+
Copy the yaml below into `.github/workflows/update-spec0.yaml`.
10+
On each run the action opens a PR updating dependency lower bounds to match the current SPEC 0 schedule.
1411

1512
```yaml
1613
name: Update SPEC 0 dependencies
1714

1815
on:
1916
schedule:
20-
# At 00:00 on day-of-month 3 in every 3rd month. (i.e. every quarter)
21-
# Releases should happen on the second day of the quarter in savente93/SPEC0-schedule to
22-
# avoid fence post errors, so allow one day as a buffer to avoid timing issues here as well.
23-
- cron: "0 0 3 */3 *"
24-
# On demand:
17+
# Day 3 of each quarter. Allows one day buffer after the quarterly schedule release on day 1
18+
- cron: "0 0 3 1,4,7,10 *"
2519
workflow_dispatch:
2620

2721
permissions:
@@ -32,32 +26,54 @@ jobs:
3226
update:
3327
runs-on: ubuntu-latest
3428
steps:
35-
- uses: scientific-python/spec0-action@v1.0.0
36-
with:
37-
token: ${{ secrets.GH_PAT }} # <- GH_PAT you will have to configure in the repo as a secret
29+
- uses: scientific-python/spec0-action@v1
3830
```
3931
40-
It should update any of the packages listed in the `dependency`, or `tool.pixi.*` tables.
41-
For examples of before and after you can see [./tests/test_data/pyproject.toml](./tests/test_data/pyproject.toml) and [./tests/test_data/pyproject_updated.toml](./tests/test_data/pyproject_updated.toml) respectively.
42-
Other tools are not yet supported, but we are open to feature requests.
43-
44-
The newest lower bounds will be downloaded from [https://github.com/scientific-python/spec0-action](https://github.com/scientific-python/spec0-action) but you should not have to worry about this.
32+
No PAT required.
33+
The built-in `GITHUB_TOKEN` is used by default as long as the workflow has `pull-requests: write` permission.
4534

4635
### Parameters
4736

48-
| Input | Required | Default | Description |
49-
| ----------------- | -------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------- |
50-
| token | yes | — | Personal access token with `contents` & `pull-request` scopes |
51-
| project_file_name | no | `"pyproject.toml"` | File to update dependencies in |
52-
| schedule_path | no | `"schedule.json"` | path to schedule json data. only relevant if you have it committed in your repo |
53-
| target_branch | no | `"main"` | Branch to open PR against |
54-
| create_pr | no | `true` | Open a PR with new versions |
55-
| pr_title | no | `chore: Drop support for unsupported packages conform SPEC 0` | The title of the PR that will be opened |
56-
| commit_msg | no | `chore: Drop support for unsupported packages conform SPEC 0` | Commit message of the commit to update the versions. |
37+
| Input | Required | Default | Description |
38+
| ------------------- | -------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
39+
| `token` | no | `GITHUB_TOKEN` | Token with `pull-requests: write` permission to open PRs |
40+
| `project_file_name` | no | `pyproject.toml` | Path to the file to update, relative to repository root |
41+
| `schedule_path` | no | — | Path to a custom `schedule.json`, relative to repository root. Uses the latest release if unset |
42+
| `target_branch` | no | `main` | Branch to open the PR against |
43+
| `create_pr` | no | `true` | Set to `false` for a dry run |
44+
| `pr_title` | no | `chore: Drop support for unsupported packages conform SPEC 0` | Title of the opened PR |
45+
| `commit_msg` | no | `chore: Drop support for unsupported packages conform SPEC 0` | Commit message for the version update commit |
46+
| `update_all` | no | — | If set to a number N, also update non-SPEC0 dependencies to versions released within the last N years (e.g. `2`) |
47+
48+
For examples of before/after see [tests/test_data/pyproject.toml](./tests/test_data/pyproject.toml) and [tests/test_data/pyproject_updated.toml](./tests/test_data/pyproject_updated.toml).
5749

5850
## Limitations
5951

60-
1. Since this action simply parses the toml to do the upgrade and leaves any other bounds intact, it is possible that the environment of the PR becomes unsolvable.
61-
For example if you have a numpy dependency like so: `numpy = ">=1.25.0,<2"` this will get updated in the PR to `numpy = ">=2.0.0,<2"` which is infeasible.
62-
Keeping the resulting environment solvable is outside the scope of this action, so you might have to adjust them manually.
63-
2. Currently only `pyproject.toml` is supported by this action, though other manifest files could be considered upon request.
52+
1. The action only tightens lower bounds and leaves upper bounds untouched. An update can produce an unsolvable environment — for example `numpy = ">=1.25.0,<2"` becomes `numpy = ">=2.0.0,<2"`. Keeping the environment solvable is out of scope; adjust upper bounds manually if needed.
53+
2. Only `pyproject.toml` is currently supported.
54+
55+
## Maintainer notes
56+
57+
### Releasing a new action version
58+
59+
Action versions are **git tags only**, do not create a GitHub Release for them. GitHub Releases in this repository are reserved for the quarterly schedule data.
60+
61+
```bash
62+
git tag v1.x
63+
git push origin v1.x
64+
```
65+
66+
### Schedule releases
67+
68+
The SPEC 0 schedule (`schedule.json` and `schedule.md`) is published as a GitHub Release quarterly by the [Update SPEC 0 schedule](./.github/workflows/update_schedule.yml) workflow. Releases are tagged `schedule-YYYY-QN` (e.g. `schedule-2026-Q2`).
69+
70+
The action always fetches `schedule.json` from the **latest** GitHub Release in this repository, which will always be a schedule release as long as action versions are never published as releases.
71+
72+
#### Bootstrap
73+
74+
Before the first quarterly schedule release exists, the action will fail. To create the initial release, trigger the workflow manually:
75+
76+
1. Go to **Actions → Update SPEC 0 schedule**
77+
2. Click **Run workflow**
78+
79+
Subsequent releases are created automatically on the 1st of January, April, July, and October.

run_spec0_update.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
parser = ArgumentParser(
88
description="A script to update your project dependencies to be in line with the scientific python SPEC 0 support schedule",
99
)
10-
1110
parser.add_argument(
1211
"toml_path",
1312
default="pyproject.toml",
@@ -18,24 +17,25 @@
1817
default="schedule.json",
1918
help="Path to the schedule json payload. defaults to 'schedule.json'",
2019
)
21-
20+
parser.add_argument(
21+
"--update-all",
22+
type=float,
23+
default=None,
24+
metavar="YEARS",
25+
help="Also update all non-SPEC0 dependencies to versions released within the last YEARS years (e.g., 2).",
26+
)
2227
args = parser.parse_args()
23-
2428
toml_path = Path(args.toml_path)
2529
schedule_path = Path(args.schedule_path)
26-
2730
if not toml_path.exists():
2831
raise ValueError(
2932
f"{toml_path} was supplied as path to project file but it did not exist"
3033
)
31-
3234
if not schedule_path.exists():
3335
raise ValueError(
3436
f"{schedule_path} was supplied as path to schedule file but it did not exist"
3537
)
36-
3738
project_data = read_toml(toml_path)
3839
schedule_data = read_schedule(schedule_path)
39-
update_pyproject_toml(project_data, schedule_data)
40-
40+
update_pyproject_toml(project_data, schedule_data, update_all=args.update_all)
4141
write_toml(toml_path, project_data)

0 commit comments

Comments
 (0)