Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/release_schedule.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
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
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
.history
chart.md
schedule.md
schedule.json
66 changes: 52 additions & 14 deletions action.yaml
Original file line number Diff line number Diff line change
@@ -1,26 +1,64 @@
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"
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 user pixi is available
- uses: prefix-dev/[email protected]
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.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 }}
74 changes: 32 additions & 42 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,53 @@
# 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/spec0-action@main
- uses: scientific-python/spec0-action@main # when this is merged and released, this should turn to @v1
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:
## Limitations

```sh
jq 'map(select(.start_date |fromdateiso8601 |tonumber < now))| sort_by("start_date") | reverse | .[0].packages ' schedule.json
```
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:

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
```
- 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
13 changes: 13 additions & 0 deletions update_pixi.sh
Original file line number Diff line number Diff line change
@@ -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
Loading