Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
d6264b8
Add a preliminary action for removing wheels
agriyakhetarpal Sep 27, 2024
9d4f667
Clarify some of the inputs, improve descriptions
agriyakhetarpal Sep 27, 2024
002d2e5
Rename original action to reflect wheel uploads
agriyakhetarpal Sep 27, 2024
40cd6bc
Convert remove wheels step to a bash script
agriyakhetarpal Sep 27, 2024
8a33f20
Fix up messages, improve comments
agriyakhetarpal Sep 27, 2024
b18b4a1
Rename org to user in sync with action's YAML
agriyakhetarpal Sep 27, 2024
deb3cba
Oops, don't let `pixi` `pip`-install `curl` and `jq`
agriyakhetarpal Sep 27, 2024
05770f3
Use `./remove-wheels` internally
agriyakhetarpal Sep 27, 2024
199b1c8
Don't mention "Anaconda Cloud" explicitly
agriyakhetarpal Sep 27, 2024
f8b96a0
Ensure consistency: use ANACONDA_USER
agriyakhetarpal Sep 27, 2024
70f8a3d
Mark TODO about macOS support
agriyakhetarpal Sep 27, 2024
2fac172
Clean up, add more TODOs and comments
agriyakhetarpal Sep 27, 2024
6a1b65e
Merge branch 'main' into feat/separate-action-for-artifact-removals
agriyakhetarpal Sep 30, 2024
8bb7bb6
Rename `anaconda_user` for consistency
agriyakhetarpal Sep 30, 2024
bae5ad6
Let ANACONDA_USER env var be empty
agriyakhetarpal Sep 30, 2024
f916adc
Merge branch 'main' into feat/separate-action-for-artifact-removals
agriyakhetarpal Sep 30, 2024
afedc16
Fix Anaconda org input
agriyakhetarpal Sep 30, 2024
35c9d59
Add some docs sections
agriyakhetarpal Sep 30, 2024
7a7dbbc
Merge branch 'main' into feat/separate-action-for-artifact-removals
bsipocz Sep 30, 2024
7830eae
Merge branch 'main' into feat/separate-action-for-artifact-removals
matthewfeickert Oct 1, 2024
2f62d85
Add some docs suggestions from code review
agriyakhetarpal Oct 1, 2024
1f04be6
Rename upload token to just token for clarity
agriyakhetarpal Oct 1, 2024
b6dbd44
Use single line for command
agriyakhetarpal Oct 1, 2024
88ce687
Fixes for `pixi` and shell script filename
agriyakhetarpal Oct 1, 2024
03979b0
Add `jq` from conda-forge as a dependency
agriyakhetarpal Oct 1, 2024
bf8e993
Revert change to "Nightly upload" section
agriyakhetarpal Oct 1, 2024
433e7c3
Revert `jq`'s addition to `pixi` global manifest file
agriyakhetarpal Oct 1, 2024
4a3497d
Add a new manifest for the `remove-wheels` environment
agriyakhetarpal Oct 1, 2024
71ede79
Generate `pixi.lock` file for `remove-wheels`
agriyakhetarpal Oct 1, 2024
2d2e62a
Add a note about how tokens for packages work
agriyakhetarpal Oct 1, 2024
556e9a6
Change to secondary-level heading
agriyakhetarpal Oct 3, 2024
e403c81
Move docs up, and workflow example below
agriyakhetarpal Oct 3, 2024
15b617e
Update pixi lockfile to be version 5 compliant
agriyakhetarpal Oct 3, 2024
288b2f2
Bump pixi lockfile to newer v6 standard
agriyakhetarpal Nov 6, 2025
9a447eb
Merge main
agriyakhetarpal Nov 6, 2025
6b0a6a1
matrix explosion for cron workflow
Cadair Nov 6, 2025
3d1fb55
Discard changes to packages-ignore-from-cleanup.txt
agriyakhetarpal Nov 6, 2025
e8796a6
Bring back package names to ignore from file
agriyakhetarpal Nov 6, 2025
b58e1ad
Bring back actions/checkout
agriyakhetarpal Nov 6, 2025
87a34c1
Merge main, fix various issues, update README
agriyakhetarpal Jul 1, 2026
dd198a5
Drop "channel" from README line
agriyakhetarpal Jul 1, 2026
8c44b1e
Update actions versions everywhere
agriyakhetarpal Jul 1, 2026
ee50125
Update base lockfile to use v7 too
agriyakhetarpal Jul 1, 2026
5bf13a4
Mark oldest versions for deletion, not newest ones
agriyakhetarpal Jul 1, 2026
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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ jobs:
if: github.repository == 'scientific-python/upload-nightly-action'

steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
# Don't rely on the action's path being in the current directory
with:
path: '_action_path'

- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.x'

Expand Down Expand Up @@ -97,7 +97,7 @@ jobs:

steps:
- name: Set up pixi
uses: prefix-dev/setup-pixi@5185adfbffb4bd703da3010310260805d89ebb11 # v0.9.6
uses: prefix-dev/setup-pixi@a09b6247153796b190642a2b53fac4241043cf6f # v0.10.0
with:
run-install: false

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/keep-alive.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ jobs:
group: ${{ github.workflow }}-${{ github.ref }}

steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Create a minimal payload
run: |
mkdir _pass
touch _pass/pass.txt

- name: Keep workflow alive
uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 #v4.1.0
uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_branch: keep-alive
Expand Down
101 changes: 33 additions & 68 deletions .github/workflows/remove-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Remove old wheels
on:
# Run daily at 1:23 UTC
schedule:
- cron: '23 1 * * *'
- cron: '23 1 * * *'
workflow_dispatch:

concurrency:
Expand All @@ -20,92 +20,57 @@ env:
ANACONDA_USER: "scientific-python-nightly-wheels"

jobs:
remove:

get-pkgs:
runs-on: ubuntu-latest
if: github.repository_owner == 'scientific-python'
# Set required workflow secrets in the environment for additional security
# https://github.com/scientific-python/upload-nightly-action/settings/environments
environment:
name: remove-old-wheels

outputs:
pkgnames: ${{ steps.set-outputs.outputs.pkgnames }}

steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install micromamba and anaconda-client
uses: mamba-org/setup-micromamba@d7c9bd84e824b79d2af72a2d4196c7f4300d3476 # v3.0.0
uses: mamba-org/setup-micromamba@d7c9bd84e824b79d2af72a2d4196c7f4300d3476 # v3.0.0
with:
environment-name: remove-wheels
create-args: >-
anaconda-client==1.14.0
curl
jq

- name: Show environment
run: env

- name: Show CLI API info
run: |
anaconda show --help
echo ""
anaconda remove --help

- name: Query package index for packages
- name: Generate list of package names

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this package list generation still necessary?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

get-pkgs generates the input matrix, so yes

id: set-outputs
run: |
curl https://raw.githubusercontent.com/scientific-python/upload-nightly-action/main/packages-ignore-from-cleanup.txt --output packages-ignore-from-cleanup.txt
anaconda show "${ANACONDA_USER}" &> >(grep "${ANACONDA_USER}/") | \
pkgs_json=$(anaconda show "${ANACONDA_USER}" 2>&1 | grep "${ANACONDA_USER}/" | \
awk '{print $1}' | \
sed 's|.*/||g' | \
grep -vf packages-ignore-from-cleanup.txt > package-names.txt

- name: Remove old uploads to save space
run: |
# Remove all _but_ the last ${N_LATEST_UPLOADS} package versions and
# remove all package versions older than 30 days.

if [ -s package-names.txt ]; then
threshold_date="$(date +%F -d '30 days ago')"

# Remember can't quote subshell as need to split on (space seperated) token
for package_name in $(cat package-names.txt); do

echo -e "\n# package: ${package_name}"

curl --silent https://api.anaconda.org/package/"${ANACONDA_USER}/${package_name}" | \
jq -r '.releases[].version' > package-versions.txt
head --lines "-${N_LATEST_UPLOADS}" package-versions.txt > remove-package-versions.txt
grep -vf packages-ignore-from-cleanup.txt | \
jq -Rn '[inputs]')
echo "pkgnames=${pkgs_json}" >> "$GITHUB_OUTPUT"

for package_version in $(cat package-versions.txt); do
# c.f. https://github.com/Anaconda-Platform/anaconda-client/issues/682#issuecomment-1677283067
upload_date=$(curl --silent https://api.anaconda.org/release/"${ANACONDA_USER}/${package_name}/${package_version}" | \
jq -r '.distributions[].upload_time' | \
sort | \
tail --lines 1 | \
awk '{print $1}')

# check upload_date is YYYY-MM-DD formatted
# c.f. https://github.com/scientific-python/upload-nightly-action/issues/73
if [[ "${upload_date}" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
if [[ "${upload_date}" < "${threshold_date}" ]]; then
echo "# ${ANACONDA_USER}/${package_name}/${package_version} last uploaded on ${upload_date}"
echo "${package_version}" >> remove-package-versions.txt
fi
else
echo "# ERROR: ${ANACONDA_USER}/${package_name}/${package_version} upload date ${upload_date} is not YYYY-MM-DD."
fi

done
remove:
runs-on: ubuntu-latest
if: github.repository_owner == 'scientific-python'
# Set required workflow secrets in the environment for additional security
# https://github.com/scientific-python/upload-nightly-action/settings/environments
environment:
name: remove-old-wheels

if [ -s remove-package-versions.txt ]; then
# Guard against duplicate entries from packages over
# count and time thresholds
sort --output remove-package-versions.txt --unique remove-package-versions.txt
needs: [get-pkgs]

for package_version in $(cat remove-package-versions.txt); do
echo "# Removing ${ANACONDA_USER}/${package_name}/${package_version}"
anaconda --token ${{ secrets.ANACONDA_TOKEN }} remove \
--force \
"${ANACONDA_USER}/${package_name}/${package_version}"
done
fi
strategy:
matrix:
pkgname: ${{fromJSON(needs.get-pkgs.outputs.pkgnames)}}

done
fi
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Remove old wheels
uses: ./remove-wheels
with:
n_latest_uploads: ${{ env.N_LATEST_UPLOADS }}
anaconda_nightly_upload_organization: ${{ env.ANACONDA_USER }}
anaconda_nightly_token: ${{ secrets.ANACONDA_TOKEN }}
package_name: ${{ matrix.pkgname }}
40 changes: 39 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,47 @@ jobs:
anaconda_nightly_upload_token: ${{secrets.UPLOAD_TOKEN}}
```

Note that we recommend pinning the action against a specific SHA
> [!IMPORTANT]
> Note that we recommend pinning the action against a specific SHA
(rather than a tag), to guard against the unlikely event of upstream
being compromised.

## Removing old nightly builds

Note that ``scientific-python-nightly-wheels``, specifically, already removes
old artifacts daily. The `remove-wheels` action is therefore intended for use with other channels.

This repository also ships with an action to ease removals of older nightly wheels from a channel.
Please note that the default configuration below will remove all but the `n_latest_uploads`
latest uploads from the channel. This is useful to avoid hosting outdated development
versions, as well as to clean up space.

If you do not wish to have this automated cleanup, please [open an issue](https://github.com/scientific-python/upload-nightly-action/)
to be added to the list of packages exempt from it. The current ones are named in
[`packages-ignore-from-cleanup.txt`](packages-ignore-from-cleanup.txt).

Please refer to the [artifact cleanup policy][] for more information.

To use this functionality, add the following snippet to your workflow:

```yml
jobs:
steps:
...
- name: Remove old wheels
uses: scientific-python/upload-nightly-action/remove-wheels@main # pin to a SHA in practice
with:
n_latest_uploads: 5
anaconda_nightly_upload_organization: "your-organization"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is called organization, not channel; are these interchangeable terms? If so, use channel; if not, explain the difference.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'm not quite sure, since they look like they have been used interchangeably. For example, the README outside of this PR:

## Using a different channel
This Github Action can upload your nightly builds to a different channel. To do so,
define the `anaconda_nightly_upload_organization` variable. Furthermore,
you can add labels for organizing your artifacts using `anaconda_nightly_upload_labels`
optional parameter. See below:
```yml
jobs:
steps:
...
- name: Upload wheel
uses: scientific-python/upload-nightly-action@82396a2ed4269ba06c6b2988bb4fd568ef3c3d6b # 0.6.1
with:
artifacts_path: dist
anaconda_nightly_upload_organization: my-alternative-organization
anaconda_nightly_upload_token: ${{secrets.UPLOAD_TOKEN}}
anaconda_nightly_upload_labels: dev
```

mentions how one may upload to a different channel, but it uses "organization" as an input.

anaconda_nightly_token: ${{secrets.ANACONDA_TOKEN}}
package_name: "your-package"
```

Please note that the `anaconda_nightly_token` secret must have the necessary permissions to
remove artifacts from the channel. A token scoped to a particular package will delete only
the artifacts for that package. If you need to delete artifacts for multiple packages, run
the action once per package (such as in a matrix).

## Updating the action

You can [use Dependabot to keep the GitHub Action up to date][],
Expand Down Expand Up @@ -112,3 +149,4 @@ dependencies:
[PyPI]: https://pypi.org/
[scientific-python nightly channel]: https://anaconda.org/scientific-python-nightly-wheels
[SPEC4 — Using and Creating Nightly Wheels]: https://scientific-python.org/specs/spec-0004/
[artifact cleanup policy]: #artifact-cleanup-policy-at-the-scientific-python-nightly-wheels-channel
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ runs:
using: "composite"
steps:
- name: Set up pixi
uses: prefix-dev/setup-pixi@5185adfbffb4bd703da3010310260805d89ebb11 # v0.9.6
uses: prefix-dev/setup-pixi@a09b6247153796b190642a2b53fac4241043cf6f # v0.10.0
with:
locked: true
cache: true
Expand Down
Loading
Loading