Skip to content
Merged
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
71 changes: 71 additions & 0 deletions .github/workflows/release_schedule.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Generate release schedule artifacts
on:
schedule:
# At 00:00 on day-of-month 2 in every 3rd month. (i.e. every quarter)
# 2nd is chosen to avoid fencepost errors
- cron: "0 0 2 */3 *"
push:
branches:
- "main"
# On demand
workflow_dispatch:

jobs:
create-artifacts:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v5
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

- uses: prefix-dev/[email protected]
with:
pixi-version: "v0.49.0"

- name: Generate artifacts
run: |
pixi run generate-schedule --locked

- name: Test json artifact
run: |
cat schedule.json | jq

- 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 "github-actions[bot]@users.noreply.github.com"

- name: determine tag name
id: tag_name
run: |
echo "TAG_NAME=$(date '+%Y-Q%q')" >> "$GITHUB_OUTPUT"
- name: Commit artifacts and create tag
env:
GH_TOKEN: ${{ secrets.RELEASE_PAT }}
run: |
git add -f schedule.md chart.md schedule.json
git commit -m "generate schedule for ${{ steps.tag_name.outputs.TAG_NAME }} release" || echo "No changes to commit"
git tag ${{ steps.tag_name.outputs.TAG_NAME }}
git push origin main
git push origin tag ${{ steps.tag_name.outputs.TAG_NAME }}

- name: Publish github release
uses: softprops/action-gh-release@v2
env:
GH_TOKEN: ${{ secrets.RELEASE_PAT }}
with:
generate_release_notes: true
tag_name: ${{ steps.tag_name.outputs.TAG_NAME }}
make_latest: true
files: |
schedule.md
chart.md
schedule.json

permissions:
contents: write
15 changes: 14 additions & 1 deletion .github/workflows/test_action.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
name: Test Action
on: [push, pull_request]
on:
push:
branches:
- "main"
- "*.*"
tags:
- "v*"
pull_request:
# Allow manual runs through the web UI
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
generate_data:
Expand Down
10 changes: 6 additions & 4 deletions .github/workflows/test_bench.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
name: Run the update test suite
on:
push:
branches: main
branches:
- "main"
- "*.*"
tags:
- "v*"
pull_request:
branches: main
# On demand
# Allow manual runs through the web UI
workflow_dispatch:

jobs:
Expand All @@ -13,7 +16,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v6

- uses: prefix-dev/[email protected]
with:
pixi-version: "v0.49.0"
Expand Down
52 changes: 21 additions & 31 deletions action.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# action.yml
name: "Update SPEC 0 dependencies"
description: "Update the lower bounds of Python dependencies covered by the Scientific Python SPEC 0 support schedule"
author: Scientific Python Developers

inputs:
target_branch:
description: "Target branch for the pull request"
Expand Down Expand Up @@ -34,63 +36,51 @@ runs:
steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Set up Git
shell: bash
run: |
git config user.name "Scientific Python [bot]"
git config user.email "[email protected]"

- uses: prefix-dev/[email protected]
name: Setup Pixi
with:
pixi-version: v0.49.0
manifest-path: ${{ github.action_path }}/pyproject.toml

- name: Regenerate schedule file if necessary
shell: bash
env:
SCHEDULE_FILE: ${{ inputs.schedule_path }}
GH_TOKEN: ${{ inputs.token }}
run: |
set -e
if [ ! -f "${{ github.workspace }}/$SCHEDULE_FILE" ]; then
echo "Regenerating schedule.json..."
pixi run generate-schedule --locked
if diff -q schedule.json "${{ github.workspace }}/$SCHEDULE_FILE" >/dev/null; then
echo "Source and destination have identical contents – nothing to move."
else
mv schedule.json "${{ github.workspace }}/$SCHEDULE_FILE"
fi
else
echo "Schedule file already exists at $SCHEDULE_FILE"
fi

- name: Fetch Schedule from release
uses: robinraju/[email protected]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely for the third party actions please use the hashes, but maybe to be consistent do it for everything.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will update

with:
repository: "savente93/SPEC0-schedule"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should not rely on a third party location for any SPEC0 related content

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree but I need to get the release working on this repo first. Or even if we want to do it in this repo or a separate repo.

latest: true
fileName: "schedule.json"
- name: Run update script
shell: bash
run: |
set -e
echo "Updating ${{inputs.project_file_name}} using schedule ${{inputs.schedule_path}}"
pixi run --manifest-path ${{ github.action_path }}/pyproject.toml update-dependencies "${{ github.workspace }}/${{ inputs.project_file_name }}" "${{ github.workspace }}/${{ inputs.schedule_path }}"

- name: Show changes (dry-run)
if: ${{ inputs.create_pr != 'true' }}
echo "Updating ${{ inputs.project_file_name }} using schedule ${{ inputs.schedule_path }}"
pixi run --manifest-path ${{ github.action_path }}/pyproject.toml update-dependencies "${{ github.workspace }}/${{ inputs.project_file_name }}" "${{ github.workspace }}/${{ inputs.schedule_path }}"
- name: Changes
id: changes
shell: bash
run: |
echo "Dry run: showing changes that would be committed"
echo "Showing changes that would be committed"
git --no-pager diff ${{ inputs.project_file_name }}

if git diff --quiet ${{ inputs.project_file_name }}; then
echo "changes_detected=false" >> "$GITHUB_OUTPUT"
else
echo "changes_detected=true" >> "$GITHUB_OUTPUT"
fi
- name: Create Pull Request
if: ${{ inputs.create_pr == 'true' }}
if: ${{ fromJSON(inputs.create_pr) && fromJSON(steps.changes.outputs.changes_detected) }}
uses: peter-evans/create-pull-request@v7
with:
token: ${{ inputs.token }}
commit-message: ${{ inputs.commit_msg }}
path: ${{ inputs.project_file_name }}
title: ${{ inputs.pr_title }}
body: "This PR was created automatically"
base: ${{ inputs.target_branch }}
branch: update-spec0-dependencies-${{ github.run_id }}
add-paths: |
${{ inputs.project_file_name }}

branding:
icon: "check-square"
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ It should update any of the packages listed in the `dependency`, or `tool.pixi.*
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.
Other tools are not yet supported, but we are open to feature requests.

The newest lower bounds will be downloaded from [https://github.com/savente93/SPEC0-schedule](https://github.com/savente93/SPEC0-schedule) but you should not have to worry about this.
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.

### Parameters

Expand Down
1 change: 0 additions & 1 deletion spec0_action/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ def update_pyproject_toml(
pyproject_data["project"]["requires-python"] = repr_spec_set(
parse_version_spec(new_version["packages"]["python"])
)

update_pyproject_dependencies(
pyproject_data["project"]["dependencies"], new_version
)
Expand Down
13 changes: 10 additions & 3 deletions spec0_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from datetime import datetime, timedelta

import pandas as pd
from packaging.version import Version
from packaging.version import Version, InvalidVersion


PY_RELEASES = {
Expand All @@ -14,6 +14,7 @@
"3.11": "Oct 24, 2022",
"3.12": "Oct 2, 2023",
"3.13": "Oct 7, 2024",
"3.14": "Oct 7, 2025",
}
CORE_PACKAGES = [
"ipython",
Expand Down Expand Up @@ -56,11 +57,17 @@ def get_release_dates(package, support_time=PLUS_24_MONTHS):
ver = f["filename"].split("-")[1]
try:
version = Version(ver)
except Exception:
except InvalidVersion as e:
print(f"Error: '{ver}' is an invalid version for '{package}'. Reason: {e}")
continue
if version.is_prerelease or version.micro != 0:
continue
release_date = pd.Timestamp(f["upload-time"]).tz_localize(None)
release_date = None
for format in ["%Y-%m-%dT%H:%M:%S.%fZ", "%Y-%m-%dT%H:%M:%SZ"]:
try:
release_date = datetime.strptime(f["upload-time"], format)
except ValueError as e:
print(f"Error parsing invalid date: {e}")
if not release_date:
continue
file_date[version].append(release_date)
Expand Down
42 changes: 14 additions & 28 deletions tests/test_data/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,30 +1,16 @@
[project]
authors = [{ name = "Scientific Python Developers"}]
name = "tests"
description = "This is just a dummy package for testing the spec 0 update github action and should not be used"
requires-python = ">=3.10"
version = "0.1.0"
dependencies = ["ipython>=8.7.0,<4", "numpy[foo,bar]>=1.10.0,<2"]

[build-system]
build-backend = "hatchling.build"
requires = ["hatchling"]

[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["linux-64"]

[tool.pixi.pypi-dependencies]
tests = { path = ".", editable = true }
scikit-learn = ">=1.2.0"
requires = [
"setuptools>=62.1",
"setuptools_scm[toml]>=8.0.0",
"wheel",
]
build-backend = "setuptools.build_meta"

[tool.pixi.tasks]

[tool.pixi.feature.foo.dependencies]
xarray = "*"

[tool.pixi.environments]
bar = ["foo"]

[tool.pixi.dependencies]
numpy = ">=1.10.0,<2"
[project]
name = "setuptools_test"
requires-python = ">=3.11"
dependencies = [
'numpy>=1.20.0,<2',
'pandas>=1.0.0,<3',
'xarray>=2021.1.0',
]
30 changes: 30 additions & 0 deletions tests/test_data/pyproject_pixi.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[project]
authors = [{ name = "Scientific Python Developers"}]
name = "tests"
description = "This is just a dummy package for testing the spec 0 update github action and should not be used"
requires-python = ">=3.10"
version = "0.1.0"
dependencies = ["ipython>=8.7.0,<4", "numpy[foo,bar]>=1.10.0,<2"]

[build-system]
build-backend = "hatchling.build"
requires = ["hatchling"]

[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["linux-64"]

[tool.pixi.pypi-dependencies]
tests = { path = ".", editable = true }
scikit-learn = ">=1.2.0"

[tool.pixi.tasks]

[tool.pixi.feature.foo.dependencies]
xarray = "*"

[tool.pixi.environments]
bar = ["foo"]

[tool.pixi.dependencies]
numpy = ">=1.10.0,<2"
30 changes: 30 additions & 0 deletions tests/test_data/pyproject_pixi_updated.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[project]
authors = [{ name = "Scientific Python Developers"}]
name = "tests"
description = "This is just a dummy package for testing the spec 0 update github action and should not be used"
requires-python = ">=3.11"
version = "0.1.0"
dependencies = ["ipython>=8.8.0,<4", "numpy[foo,bar]>=1.25.0,<2"]

[build-system]
build-backend = "hatchling.build"
requires = ["hatchling"]

[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["linux-64"]

[tool.pixi.pypi-dependencies]
tests = { path = ".", editable = true }
scikit-learn = ">=1.3.0"

[tool.pixi.tasks]

[tool.pixi.feature.foo.dependencies]
xarray = ">=2023.1.0"

[tool.pixi.environments]
bar = ["foo"]

[tool.pixi.dependencies]
numpy = ">=1.25.0,<2"
Loading