From 82adfab84abde452d7870eeb3d06cd9bfe6535d7 Mon Sep 17 00:00:00 2001 From: Martin Fleischmann Date: Mon, 22 May 2023 16:36:12 -0700 Subject: [PATCH 01/20] update token info and conda xml instructions --- README.md | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 8dbfd0f..4d2ef43 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ -# nightly uplolad. - +# Nightly upload This provides a standard GitHub Action to upload nightly builds to the -scientific-python nightly channel. +scientific-python nightly channel. In your Continuous Intregration pipeline once you've built you wheel, you can use the following snippet to upload to our central nightly repository: - ```yml jobs: steps: @@ -19,24 +17,23 @@ jobs: anaconda_nightly_upload_token: ${{secrets.UPLOAD_TOKEN}} ``` - To request access to the repository please open an issue on [this action repository](https://github.com/scientific-python/upload-nightly-action). You can -then generate a token at `https://anaconda.org//settings/access`, check -minimum permissions and add the token as a secret to your GitHub repository. +then generate a token at `https://anaconda.org/scientific-python-nightly-wheels/settings/access` +with _Allow write access to the API site_ and _Allow uploads to Standard Python repositories_ +permissions and add the token as a secret to your GitHub repository. - -# using nightly builds in CI. +# Using nightly builds in CI To test those nightly build, you can use the following command to install from -the nightly package. +the nightly package. -``` +```sh python -m pip install matplotlib -i https://pypi.org/simple -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --upgrade --pre ``` Note that second `-i` parameter will take priority, it needs to come second if -you want to pull from nightly otherwise it will pull from pypi. +you want to pull from nightly otherwise it will pull from PyPI. ``` if package in nightly: @@ -44,3 +41,15 @@ if package in nightly: else: try to install from pypi ``` + +If you want to install nightly builds within your conda environment, you can specify an +extra index in your YML file. + +```yml +name: test +dependencies: + - pip + - pip: + - --pre --extra-index https://pypi.anaconda.org/scientific-python-nightly-wheels/simple + - matplotlib +``` From 80af44feb2d73fe29869d46207c02f88885ea5b8 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Tue, 23 May 2023 14:57:54 -0700 Subject: [PATCH 02/20] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d2ef43..d8c8ac0 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ To test those nightly build, you can use the following command to install from the nightly package. ```sh -python -m pip install matplotlib -i https://pypi.org/simple -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --upgrade --pre +python -m pip install matplotlib --extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --upgrade --pre ``` Note that second `-i` parameter will take priority, it needs to come second if From a45c843fe72f542bbf16ca9e9d8043f5f1088004 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Tue, 30 May 2023 00:39:15 -0500 Subject: [PATCH 03/20] DOC: Use scientific-python-nightly-wheels for nightly build index * Use of --index-url for the nightly package index and --extra-index-url for public PyPI (https://pypi.org/) makes the behavior of installation precedence more explicit. --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d8c8ac0..312a4ef 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,12 @@ To test those nightly build, you can use the following command to install from the nightly package. ```sh -python -m pip install matplotlib --extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --upgrade --pre +python -m pip install \ + --upgrade \ + --pre \ + --index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple \ + --extra-index-url https://pypi.org/simple \ + matplotlib ``` Note that second `-i` parameter will take priority, it needs to come second if @@ -50,6 +55,6 @@ name: test dependencies: - pip - pip: - - --pre --extra-index https://pypi.anaconda.org/scientific-python-nightly-wheels/simple + - --pre --index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --extra-index-url https://pypi.org/simple - matplotlib ``` From b349f162ff338ad0dca27df4fedd5387fd62cfa4 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Tue, 30 May 2023 00:42:57 -0500 Subject: [PATCH 04/20] DOC: Add short explanation of index-url priority * Provide a very short summary of how --index-url takes priority over --extra-index-url to ensure that if a target package exists on the nightly package index it will be used over a version that exists on public PyPI (https://pypi.org/). --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 312a4ef..65019dd 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,10 @@ python -m pip install \ matplotlib ``` -Note that second `-i` parameter will take priority, it needs to come second if -you want to pull from nightly otherwise it will pull from PyPI. +Note that `--index-url` takes priority over `--extra-index-url`. +Packages, and dependencies, with versions available on the +[nightly package index][] will be installed from there before falling back to +the [Python Package Index][PyPI] to install all remaining requested packages. ``` if package in nightly: @@ -58,3 +60,6 @@ dependencies: - --pre --index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --extra-index-url https://pypi.org/simple - matplotlib ``` + +[nightly package index]: https://anaconda.org/scientific-python-nightly-wheels +[PyPI]: https://pypi.org/ From 468089a62082abf7e842d6e16fc0786ffd8f6872 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 8 Jun 2023 10:59:38 -0500 Subject: [PATCH 05/20] DOC: Advocate for using action from tagged release commit shas (#13) * DOC: Advocate for using action from tagged release commit SHAs * For security best practices, advocate that users of the action use it from known commit SHAs that correspond to tagged releases. * Advocate that users use a Dependabot config file to update the action on new tags. This will bump the commit SHA and also bump the release tag in the comment of the commit SHA. - c.f. https://learn.scientific-python.org/development/guides/gha_basic/#updating * DOC: Fix typo * 'Intregration' -> 'Integration' * Tighten up README --------- Co-authored-by: Stefan van der Walt --- README.md | 65 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 65019dd..a8022b9 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,53 @@ # Nightly upload -This provides a standard GitHub Action to upload nightly builds to the -scientific-python nightly channel. +This is a GitHub Action that uploads nightly builds to the [scientific-python nightly channel][], +as recommended in [SPEC4 — Using and Creating Nightly Wheels][]. -In your Continuous Intregration pipeline once you've built you wheel, you can -use the following snippet to upload to our central nightly repository: +In a GitHub Actions workflow (`.github/workflows/*.yaml`), use the +following snippet to upload built wheels to the repository: ```yml jobs: steps: ... - name: Upload wheel - uses: scientific-python/upload-nightly-action@main + uses: scientific-python/upload-nightly-action@8f0394fd2aa0c85d7364a9958652e8994e06b23c # 0.1.0 with: artifacts_path: dist anaconda_nightly_upload_token: ${{secrets.UPLOAD_TOKEN}} ``` -To request access to the repository please open an issue on [this action +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. + +# Updating the action + +You can [use Dependabot to keep the GitHub Action up to date][], +with a `.github/dependabot.yml` config file similar to: + +```yaml +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" +``` + +# Access + +To request access to the repository, please open an issue on [this action's repository](https://github.com/scientific-python/upload-nightly-action). You can then generate a token at `https://anaconda.org/scientific-python-nightly-wheels/settings/access` -with _Allow write access to the API site_ and _Allow uploads to Standard Python repositories_ -permissions and add the token as a secret to your GitHub repository. +with permissions to _Allow write access to the API site_ and _Allow uploads to Standard Python repositories_, +and add the token as a secret to your GitHub repository. # Using nightly builds in CI -To test those nightly build, you can use the following command to install from -the nightly package. +To test against nightly builds, you can use the following command to install from +the nightly repository: ```sh python -m pip install \ @@ -37,29 +58,23 @@ python -m pip install \ matplotlib ``` -Note that `--index-url` takes priority over `--extra-index-url`. -Packages, and dependencies, with versions available on the -[nightly package index][] will be installed from there before falling back to -the [Python Package Index][PyPI] to install all remaining requested packages. - -``` -if package in nightly: - try to install from nightly -else: - try to install from pypi -``` +Note that `--index-url` takes priority over `--extra-index-url`, so +that packages, and their dependencies, with versions available in the +nightly channel will be installed before falling back to the [Python +Package Index][PyPI]. -If you want to install nightly builds within your conda environment, you can specify an -extra index in your YML file. +To install nightly builds within a conda environment, specify an extra +index in your `environment.yml`: ```yml name: test dependencies: - - pip - pip: - --pre --index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --extra-index-url https://pypi.org/simple - matplotlib ``` -[nightly package index]: https://anaconda.org/scientific-python-nightly-wheels +[use Dependabot to keep the GitHub Action up to date]: https://learn.scientific-python.org/development/guides/gha_basic/#updating [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/ From 0792f724d7df7b8cc65f8039dfd12c9852a1b65f Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Thu, 8 Jun 2023 09:11:29 -0700 Subject: [PATCH 06/20] In `environment.yaml`, add pip as dependency before configuring flags (#16) The previous approach works with mamba and conda, but not with micromamba. So this adds `pip` back as an explicit dependency, before configuring pip installation flags. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a8022b9..6c3414b 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ index in your `environment.yml`: ```yml name: test dependencies: + - pip - pip: - --pre --index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --extra-index-url https://pypi.org/simple - matplotlib From c049309f3375008b07cc8dd446a461b02de87603 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 9 Jun 2023 11:38:59 -0500 Subject: [PATCH 07/20] CI: Add removal of old uploads (#12) * CI: Add old wheel removal GitHub Actions workflow * Add GitHub Actions workflow to remove old wheels from the package index each night at 1:23 UTC. Also allow for manual runs via workflow dispatch. * Remove all but the last N_LATEST_UPLOADS package version uploads to the package index to ensure space. To do this, reply on the output form of `anaconda show` to be able to filter on the item delimiter character sequence for each version currently uploaded. As an explicit example: ``` $ anaconda show scientific-python-nightly-wheels/xarray Using Anaconda API: https://api.anaconda.org Name: xarray Summary: Access: public Package Types: Standard Python Versions: + 2023.5.1.dev9+g609a9016 + 2023.5.1.dev10+gf45eb733 + 2023.5.1.dev11+gfcb81756 + 2023.5.1.dev12+gb319d867 + 2023.5.1.dev14+ge3db6164 To install this package with pypi run: pip install -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple xarray ``` shows that by filtering on '+' and then stripping ' + ' one can obtain a newline separated list of all package uploads, where the _most recent_ uploads are listed last. After stripping off the N_LATEST_UPLOADS lines that correspond to the package versions to keep for testing, the remaining (older) package uploads can be removed with `anaconda remove`. * CI: Add Dependabot config file for GitHub Actions * Use Dependabot to keep the GitHub Actions used in workflows up to date. --- .github/dependabot.yml | 9 ++++ .github/workflows/remove-wheels.yml | 81 +++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/remove-wheels.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..c2139ea --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + labels: + - "github-actions" diff --git a/.github/workflows/remove-wheels.yml b/.github/workflows/remove-wheels.yml new file mode 100644 index 0000000..45f6706 --- /dev/null +++ b/.github/workflows/remove-wheels.yml @@ -0,0 +1,81 @@ +name: Remove old wheels + +on: + # Run daily at 1:23 UTC + schedule: + - cron: '23 1 * * *' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +# Needed for micromamba pickup +defaults: + run: + shell: bash -l {0} + +env: + N_LATEST_UPLOADS: 5 + ANACONDA_USER: "scientific-python-nightly-wheels" + +jobs: + remove: + + runs-on: ubuntu-latest + # 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 + + steps: + - name: Install micromamba and anaconda-client + uses: mamba-org/setup-micromamba@v1 + with: + environment-name: remove-wheels + create-args: >- + python=3.11 + anaconda-client=1.11.2 + + - name: Show environment + run: env + + - name: Show CLI API info + run: | + anaconda show --help + echo "" + anaconda remove --help + + - name: Query package index for packages + run: | + anaconda show "${ANACONDA_USER}" &> >(grep "${ANACONDA_USER}/") | \ + awk '{print $1}' | \ + sed 's|.*/||g' > package-names.txt + + - name: Remove old uploads to save space + run: | + # Remove all _but_ the last ${N_LATEST_UPLOADS} package versions + # N.B.: `anaconda show` places the newest packages at the bottom of the output + # of the 'Versions' section and package versions are preceded with a ' + '. + + if [ -s package-names.txt ]; then + # 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}" + + anaconda show "${ANACONDA_USER}/${package_name}" &> >(grep '+') | \ + awk '{print $2}' | \ + head --lines "-${N_LATEST_UPLOADS}" > remove-package-versions.txt + + if [ -s remove-package-versions.txt ]; then + 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 + + done + fi From b1c5a48e464ab8a45a1899cfaefc21548923ee6d Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Mon, 12 Jun 2023 02:39:42 -0500 Subject: [PATCH 08/20] CI: Add workflow to avoid scheduled workflows becoming disabled (#18) Resolves #17 * Run a cron job on a monthly basis that force pushes a commit to a keep-alive branch. --- .github/workflows/keep-alive.yml | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/keep-alive.yml diff --git a/.github/workflows/keep-alive.yml b/.github/workflows/keep-alive.yml new file mode 100644 index 0000000..5d35359 --- /dev/null +++ b/.github/workflows/keep-alive.yml @@ -0,0 +1,38 @@ +name: Keep workflows alive + +on: + # Run on the first of each month at 1:23 UTC + schedule: + - cron: '23 1 1 * *' + workflow_dispatch: + +jobs: + deploy: + + runs-on: ubuntu-latest + + permissions: + contents: write + + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + + steps: + - uses: actions/checkout@v3 + + - name: Create a minimal payload + run: | + mkdir _pass + touch _pass/pass.txt + + - name: Keep workflow alive + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_branch: keep-alive + publish_dir: _pass + enable_jekyll: true # avoid extra files + force_orphan: true # overwirte + user_name: 'github-actions[bot]' + user_email: 'github-actions[bot]@users.noreply.github.com' + commit_message: Keep repo GitHub Actions alive From a147ec2ad33ee6d9c76233ccdd0f552154bcaabc Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Tue, 13 Jun 2023 09:41:22 -0500 Subject: [PATCH 09/20] MNT: Use commit hash and run only on main repository (#19) * MNT: Use commit hash as peaceiris/actions-gh-page has write access * MNT: Run only on main repository * Running on forks lacks permissions and will cause failures. --- .github/workflows/keep-alive.yml | 2 +- .github/workflows/remove-wheels.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/keep-alive.yml b/.github/workflows/keep-alive.yml index 5d35359..87bd679 100644 --- a/.github/workflows/keep-alive.yml +++ b/.github/workflows/keep-alive.yml @@ -26,7 +26,7 @@ jobs: touch _pass/pass.txt - name: Keep workflow alive - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@373f7f263a76c20808c831209c920827a82a2847 #v3.9.3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_branch: keep-alive diff --git a/.github/workflows/remove-wheels.yml b/.github/workflows/remove-wheels.yml index 45f6706..9b3665e 100644 --- a/.github/workflows/remove-wheels.yml +++ b/.github/workflows/remove-wheels.yml @@ -23,6 +23,7 @@ jobs: 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: From c5542a05cb083c1bb404661f128c6cf53c48d890 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Tue, 18 Jul 2023 14:53:58 -0500 Subject: [PATCH 10/20] ENH: Use micromamba for speed and set anaconda-client version (#23) * ENH: Use micromamba - Use mambaorg/micromamba:1.4.9-bullseye-slim as base image. - Set container shell to Bash explicitly. - Use C.UTF-8 to avoid issues with unicode. * MNT: Set anaconda-client version for security stability - Explicitly set the anaconda-client version to know what version is being used for upload. - Use anaconda-client v1.12.0 to aovid CONDA_ROOT micromamba config error. - c.f. https://github.com/Anaconda-Platform/anaconda-client/issues/636 * MNT: Use full CLI API options and quote guard shell variables --- .github/workflows/remove-wheels.yml | 2 +- Dockerfile | 8 +++++++- entrypoint.sh | 20 ++++++++++++++------ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/.github/workflows/remove-wheels.yml b/.github/workflows/remove-wheels.yml index 9b3665e..ef1017f 100644 --- a/.github/workflows/remove-wheels.yml +++ b/.github/workflows/remove-wheels.yml @@ -36,7 +36,7 @@ jobs: environment-name: remove-wheels create-args: >- python=3.11 - anaconda-client=1.11.2 + anaconda-client=1.12.0 - name: Show environment run: env diff --git a/Dockerfile b/Dockerfile index ee82c43..e0c2073 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,10 @@ -FROM continuumio/miniconda3:latest +FROM mambaorg/micromamba:1.4.9-bullseye-slim + +SHELL [ "/bin/bash", "-c" ] + +# Use C.UTF-8 locale to avoid issues with unicode encoding +ENV LC_ALL=C.UTF-8 +ENV LANG=C.UTF-8 COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh diff --git a/entrypoint.sh b/entrypoint.sh index 9eee793..57a8ffc 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -15,19 +15,24 @@ set -x echo "Getting anaconda token from github secrets..." ANACONDA_ORG="scientific-python-nightly-wheels" -ANACONDA_TOKEN="$INPUT_ANACONDA_NIGHTLY_UPLOAD_TOKEN" +ANACONDA_TOKEN="${INPUT_ANACONDA_NIGHTLY_UPLOAD_TOKEN}" # if the ANACONDA_TOKEN is empty, exit with status -1 # this is to prevent accidental uploads -if [ -z "$ANACONDA_TOKEN" ]; then +if [ -z "${ANACONDA_TOKEN}" ]; then echo "ANACONDA_TOKEN is empty , exiting..." exit -1 fi +export ANACONDA_CLIENT_VERSION="1.12.0" + # install anaconda-client -echo "Installing anaconda-client..." +echo "Installing anaconda-client v${ANACONDA_CLIENT_VERSION}..." -conda install -y anaconda-client -c conda-forge +micromamba install \ + --yes \ + --channel conda-forge \ + "anaconda-client==${ANACONDA_CLIENT_VERSION}" # trim trailing slashes from $INPUT_ARTIFACTS_PATH INPUT_ARTIFACTS_PATH="${INPUT_ARTIFACTS_PATH%/}" @@ -38,5 +43,8 @@ env # upload wheels echo "Uploading wheels to anaconda.org..." -anaconda -t $ANACONDA_TOKEN upload --force -u "$ANACONDA_ORG" "$INPUT_ARTIFACTS_PATH"/*.whl -echo "Index: https://pypi.anaconda.org/$ANACONDA_ORG/simple" +anaconda --token "${ANACONDA_TOKEN}" upload \ + --force \ + --user "${ANACONDA_ORG}" \ + "${INPUT_ARTIFACTS_PATH}"/*.whl +echo "Index: https://pypi.anaconda.org/${ANACONDA_ORG}/simple" From e09d83f8a9d79b1998dd94cd9fd5115162961820 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Tue, 18 Jul 2023 15:02:40 -0500 Subject: [PATCH 11/20] DOC: Fix broken url to Scientific Python Development Guide (#24) * At some point urls were changed to use '-' over '_'. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c3414b..d31697a 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ dependencies: - matplotlib ``` -[use Dependabot to keep the GitHub Action up to date]: https://learn.scientific-python.org/development/guides/gha_basic/#updating +[use Dependabot to keep the GitHub Action up to date]: https://learn.scientific-python.org/development/guides/gha-basic/#updating [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/ From 4792bc241c0a689e41f0fc4bf0953f26b8324c7b Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Wed, 19 Jul 2023 13:43:54 -0500 Subject: [PATCH 12/20] FIX: Ensure USER has permissions for chmod in Dockerfile (#26) * FIX: Ensure USER has permissions for chmod in Dockerfile * For security reasons the default user in mambaorg/micromamba:1.4.9-bullseye-slim is non-root with uid 1000 (mambauser) but this requires the user permissions to be escalated to one with chmod powers. The simplest way to do this is to chown to mambauser on COPY. * To ensure that the micromamba environment is setup correctly on entry fallback to the mambaorg/micromamba's base image ENTRYPOINT and set this action's /entrypoint.sh as CMD. - c.f. https://github.com/mamba-org/micromamba-docker/blob/604ebafb09543a3d852e437886f1c782f0367911/_entrypoint.sh * MNT: Rename action's script from entrypoint.sh to cmd.sh for clarity * As the action is relying on the mambaorg/micromamba container's entrypoint to setup the shell environment correctly let this be clearly the ENTRYPOINT and rename the action's entrypoint script to cmd.sh as it is being passed as CMD. --- Dockerfile | 15 ++++++++++++--- entrypoint.sh => cmd.sh | 0 2 files changed, 12 insertions(+), 3 deletions(-) rename entrypoint.sh => cmd.sh (100%) diff --git a/Dockerfile b/Dockerfile index e0c2073..d168c4c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,21 @@ FROM mambaorg/micromamba:1.4.9-bullseye-slim +USER mambauser + SHELL [ "/bin/bash", "-c" ] # Use C.UTF-8 locale to avoid issues with unicode encoding ENV LC_ALL=C.UTF-8 ENV LANG=C.UTF-8 -COPY entrypoint.sh /entrypoint.sh -RUN chmod +x /entrypoint.sh +COPY --chown=mambauser cmd.sh /cmd.sh +RUN chmod +x /cmd.sh -ENTRYPOINT ["/entrypoint.sh"] +# The mambaorg/micromamba base image's entrypoint is +# /usr/local/bin/_entrypoint.sh which ensures the shell environment is +# correctly set for micromamba to be accessible by the given user. +# c.f. https://github.com/mamba-org/micromamba-docker/blob/604ebafb09543a3d852e437886f1c782f0367911/_entrypoint.sh +# Instead of replicating this, continue to use it as the ENTRYPOINT +# and then pass the action's script as CMD. +ENTRYPOINT [ "/usr/local/bin/_entrypoint.sh" ] +CMD [ "/cmd.sh" ] diff --git a/entrypoint.sh b/cmd.sh similarity index 100% rename from entrypoint.sh rename to cmd.sh From a2ba178f650e68bd6f9d8e2b7d59d16ffd257c29 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 20 Jul 2023 23:11:34 -0500 Subject: [PATCH 13/20] MNT: Align version metadata with git tag (#28) * The latest repository tag is 0.1.0 and so the action version metadata should reflect that as well. --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 115a3b3..6f84f14 100644 --- a/action.yml +++ b/action.yml @@ -5,7 +5,7 @@ permissions: contents: read metadata: read author: "Scientific-Python" -version: "1.0.0" +version: "0.1.0" inputs: artifacts_path: From b4720c6120f4b351ecfa8ca688459e31d440d6af Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Wed, 9 Aug 2023 17:11:59 -0500 Subject: [PATCH 14/20] CI: Add test workflow for action (#27) * Add simplest example package to tests so that it can be built for upload to Anaconda cloud as a test of the action. - Use setuptools as the build backend over something more obvious like hatchling given the simple nature of the test-package given that anaconda-client v1.12.0 doesn't understand valid metadata from PEP 518 build backends other than setuptools. c.f. https://github.com/Anaconda-Platform/anaconda-client/issues/676 * Add CI GitHub Action workflow to test the functionality of the action as shown in the README. --- .github/workflows/ci.yml | 78 +++++++++++++++++++ tests/test_package/README.md | 1 + tests/test_package/pyproject.toml | 13 ++++ .../test_package/src/test_package/__init__.py | 0 4 files changed, 92 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 tests/test_package/README.md create mode 100644 tests/test_package/pyproject.toml create mode 100644 tests/test_package/src/test_package/__init__.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..128e42c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,78 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + # Run weekly at 1:23 UTC + schedule: + - cron: '23 1 * * 0' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: "test upload via action" + runs-on: ubuntu-latest + if: github.repository == 'scientific-python/upload-nightly-action' + + steps: + - uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.x' + + - name: Install python-build and twine + run: | + python -m pip install --upgrade pip + python -m pip install build twine + python -m pip list + + - name: Build a wheel and a sdist + run: | + PYTHONWARNINGS=error,default::DeprecationWarning python -m build --outdir ./dist tests/test_package + + - name: Verify the distribution + run: twine check --strict dist/* + + - name: List contents of sdist + run: python -m tarfile --list dist/test-package-*.tar.gz + + - name: List contents of wheel + run: python -m zipfile --list dist/test_package-*.whl + + - name: Test upload + uses: ./ + with: + artifacts_path: dist + anaconda_nightly_upload_token: ${{ secrets.UPLOAD_TOKEN }} + + cleanup: + runs-on: ubuntu-latest + needs: [test] + # 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 + + steps: + - name: Install micromamba and anaconda-client + uses: mamba-org/setup-micromamba@v1 + with: + environment-name: remove-wheels + create-args: >- + python=3.11 + anaconda-client + + - name: Remove test package upload + shell: bash -l {0} + run: | + anaconda --token ${{ secrets.ANACONDA_TOKEN }} remove \ + --force \ + "scientific-python-nightly-wheels/test-package" diff --git a/tests/test_package/README.md b/tests/test_package/README.md new file mode 100644 index 0000000..e8f9bf7 --- /dev/null +++ b/tests/test_package/README.md @@ -0,0 +1 @@ +# Test README diff --git a/tests/test_package/pyproject.toml b/tests/test_package/pyproject.toml new file mode 100644 index 0000000..ee79214 --- /dev/null +++ b/tests/test_package/pyproject.toml @@ -0,0 +1,13 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "test-package" +version = "0.0.1" +authors = [ + { name="Scientifc Python Developers", email="null@example.com" }, +] +description = "Test project for testing GitHub Action" +readme = "README.md" +requires-python = ">=3.8" diff --git a/tests/test_package/src/test_package/__init__.py b/tests/test_package/src/test_package/__init__.py new file mode 100644 index 0000000..e69de29 From 2b318b62a3436c8e05b7ed8d169a6feff8e9b537 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Mon, 14 Aug 2023 17:08:58 -0500 Subject: [PATCH 15/20] CI: Remove package versions older than 30 days (#33) * CI: Remove package versions older than 30 days * Add curl and jq to environment requirements. * Use output from the anaconda.org API to get latest upload time for each release of a package. If the upload date is older than 30 days add the package release for removal. * Use anaconda.org API over anaconda-client CLI API to get package versions as easier to understand. * Guard against duplicate entries --- .github/workflows/remove-wheels.yml | 33 +++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/.github/workflows/remove-wheels.yml b/.github/workflows/remove-wheels.yml index ef1017f..d39b5dd 100644 --- a/.github/workflows/remove-wheels.yml +++ b/.github/workflows/remove-wheels.yml @@ -37,6 +37,8 @@ jobs: create-args: >- python=3.11 anaconda-client=1.12.0 + curl + jq - name: Show environment run: env @@ -55,21 +57,40 @@ jobs: - name: Remove old uploads to save space run: | - # Remove all _but_ the last ${N_LATEST_UPLOADS} package versions - # N.B.: `anaconda show` places the newest packages at the bottom of the output - # of the 'Versions' section and package versions are preceded with a ' + '. + # 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}" - anaconda show "${ANACONDA_USER}/${package_name}" &> >(grep '+') | \ - awk '{print $2}' | \ - head --lines "-${N_LATEST_UPLOADS}" > remove-package-versions.txt + 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 + + 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}') + + 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 + done 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 + for package_version in $(cat remove-package-versions.txt); do echo "# Removing ${ANACONDA_USER}/${package_name}/${package_version}" anaconda --token ${{ secrets.ANACONDA_TOKEN }} remove \ From bb8679daeae11bebce0efece929d4a4f899a2886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Thu, 17 Aug 2023 10:26:05 -0700 Subject: [PATCH 16/20] ENH: adding list of packages to exclude from cleanup (#36) --- .github/workflows/remove-wheels.yml | 4 +++- packages-ignore-from-cleanup.txt | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 packages-ignore-from-cleanup.txt diff --git a/.github/workflows/remove-wheels.yml b/.github/workflows/remove-wheels.yml index d39b5dd..b27d260 100644 --- a/.github/workflows/remove-wheels.yml +++ b/.github/workflows/remove-wheels.yml @@ -51,9 +51,11 @@ jobs: - name: Query package index for packages 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}/") | \ awk '{print $1}' | \ - sed 's|.*/||g' > package-names.txt + sed 's|.*/||g' | \ + grep -vf packages-ignore-from-cleanup.txt > package-names.txt - name: Remove old uploads to save space run: | diff --git a/packages-ignore-from-cleanup.txt b/packages-ignore-from-cleanup.txt new file mode 100644 index 0000000..ce4a1d4 --- /dev/null +++ b/packages-ignore-from-cleanup.txt @@ -0,0 +1 @@ +openblas-libs From 920f5132d3a0230111fe72fa9f954c23b882bb96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Thu, 17 Aug 2023 14:19:43 -0700 Subject: [PATCH 17/20] DOC: some cleanup in the readme, and some heading hierarcy (#37) --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d31697a..d8a1366 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ 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. -# Updating the action +## Updating the action You can [use Dependabot to keep the GitHub Action up to date][], with a `.github/dependabot.yml` config file similar to: @@ -36,14 +36,15 @@ updates: interval: "weekly" ``` -# Access +## Access to the ``scientific-python-nightly-wheels`` space -To request access to the repository, please open an issue on [this action's +To request access to the wheel channel, please open an issue on [the upload action's repository](https://github.com/scientific-python/upload-nightly-action). You can then generate a token at `https://anaconda.org/scientific-python-nightly-wheels/settings/access` with permissions to _Allow write access to the API site_ and _Allow uploads to Standard Python repositories_, and add the token as a secret to your GitHub repository. + # Using nightly builds in CI To test against nightly builds, you can use the following command to install from From ae4395280cc54a849801b0db1d19bbcb816341f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Sat, 19 Aug 2023 03:21:19 -0700 Subject: [PATCH 18/20] DOC: add channel retention policy (#38) --- README.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d8a1366..68d9eaf 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This is a GitHub Action that uploads nightly builds to the [scientific-python ni as recommended in [SPEC4 — Using and Creating Nightly Wheels][]. In a GitHub Actions workflow (`.github/workflows/*.yaml`), use the -following snippet to upload built wheels to the repository: +following snippet to upload built wheels to the channel: ```yml jobs: @@ -36,7 +36,7 @@ updates: interval: "weekly" ``` -## Access to the ``scientific-python-nightly-wheels`` space +## Access to the ``scientific-python-nightly-wheels`` channel To request access to the wheel channel, please open an issue on [the upload action's repository](https://github.com/scientific-python/upload-nightly-action). You can @@ -44,11 +44,22 @@ then generate a token at `https://anaconda.org/scientific-python-nightly-wheels/ with permissions to _Allow write access to the API site_ and _Allow uploads to Standard Python repositories_, and add the token as a secret to your GitHub repository. +## Artifact cleanup-policy at the ``scientific-python-nightly-wheels`` channel + +To avoid hosting outdated development versions, as well as to clean up space, we do have a +default retention policy of: + +- Latest **5 versions** +- Artifacts newer than **30 days** + +Any versions beyond these are automatically removed as part of a daily cron job run from this repository. +Projects may have reasons to request to be added to the list exempt from this automated cleanup, however +in that case the responsibility of cleaning-up old, unused versions fall back on the individual project. # Using nightly builds in CI To test against nightly builds, you can use the following command to install from -the nightly repository: +the nightly channel: ```sh python -m pip install \ From a5947da1003e7ba956247f0b3fea92d559b5f925 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 18:12:04 -0500 Subject: [PATCH 19/20] Bump actions/checkout from 3 to 4 (#40) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/keep-alive.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 128e42c..6ff853c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: if: github.repository == 'scientific-python/upload-nightly-action' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 diff --git a/.github/workflows/keep-alive.yml b/.github/workflows/keep-alive.yml index 87bd679..842186d 100644 --- a/.github/workflows/keep-alive.yml +++ b/.github/workflows/keep-alive.yml @@ -18,7 +18,7 @@ jobs: group: ${{ github.workflow }}-${{ github.ref }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Create a minimal payload run: | From 5fb764c5bce1ac2297084c0f7161b1919f17c74f Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 6 Oct 2023 11:24:32 -0500 Subject: [PATCH 20/20] MNT: Use conda-lock lock file for reproducible environment (#32) * Add lock.sh which uses the same Docker image used for deployment to install conda-lock and then build the conda-lock lock file from the high level environment.yml. * Add high level environment.yml and use conda-lock v2.x to create a hash level conda-lock.yml lock file of the environment. ``` conda-lock lock --micromamba --platform linux-64 --file environment.yml ``` * COPY conda-lock.yml lock file to Dockerfile during build. * Use the conda-lock.yml lock file to create an upload-nightly-action micromamba environment and activate it to have access to anaconda-client. --- .github/workflows/remove-wheels.yml | 2 +- Dockerfile | 2 + cmd.sh | 18 +- conda-lock.yml | 1163 +++++++++++++++++++++++++++ environment.yml | 6 + lock.sh | 16 + 6 files changed, 1198 insertions(+), 9 deletions(-) create mode 100644 conda-lock.yml create mode 100644 environment.yml create mode 100644 lock.sh diff --git a/.github/workflows/remove-wheels.yml b/.github/workflows/remove-wheels.yml index b27d260..007e449 100644 --- a/.github/workflows/remove-wheels.yml +++ b/.github/workflows/remove-wheels.yml @@ -36,7 +36,7 @@ jobs: environment-name: remove-wheels create-args: >- python=3.11 - anaconda-client=1.12.0 + anaconda-client=1.12.1 curl jq diff --git a/Dockerfile b/Dockerfile index d168c4c..1e0e46a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,8 @@ SHELL [ "/bin/bash", "-c" ] ENV LC_ALL=C.UTF-8 ENV LANG=C.UTF-8 +# lock file created by running lock.sh in the top level of the repository +COPY --chown=mambauser conda-lock.yml /conda-lock.yml COPY --chown=mambauser cmd.sh /cmd.sh RUN chmod +x /cmd.sh diff --git a/cmd.sh b/cmd.sh index 57a8ffc..8313e8e 100644 --- a/cmd.sh +++ b/cmd.sh @@ -24,15 +24,17 @@ if [ -z "${ANACONDA_TOKEN}" ]; then exit -1 fi -export ANACONDA_CLIENT_VERSION="1.12.0" - -# install anaconda-client -echo "Installing anaconda-client v${ANACONDA_CLIENT_VERSION}..." - -micromamba install \ +# Install anaconda-client from lock file +echo "Installing anaconda-client from upload-nightly-action conda-lock lock file..." +micromamba create \ --yes \ - --channel conda-forge \ - "anaconda-client==${ANACONDA_CLIENT_VERSION}" + --name upload-nightly-action \ + --file /conda-lock.yml + +# 'micromamba' is running as a subprocess and can't modify the parent shell. +# Thus you must initialize your shell before using activate and deactivate. +eval "$(micromamba shell hook --shell bash)" +micromamba activate upload-nightly-action # trim trailing slashes from $INPUT_ARTIFACTS_PATH INPUT_ARTIFACTS_PATH="${INPUT_ARTIFACTS_PATH%/}" diff --git a/conda-lock.yml b/conda-lock.yml new file mode 100644 index 0000000..de4dc92 --- /dev/null +++ b/conda-lock.yml @@ -0,0 +1,1163 @@ +# This lock file was generated by conda-lock (https://github.com/conda/conda-lock). DO NOT EDIT! +# +# A "lock file" contains a concrete list of package versions (with checksums) to be installed. Unlike +# e.g. `conda env create`, the resulting environment will not change as new package versions become +# available, unless you explicitly update the lock file. +# +# Install this environment as "YOURENV" with: +# conda-lock install -n YOURENV --file conda-lock.yml +# To update a single package to the latest version compatible with the version constraints in the source: +# conda-lock lock --lockfile conda-lock.yml --update PACKAGE +# To re-solve the entire environment, e.g. after changing a version constraint in the source file: +# conda-lock -f environment.yml --lockfile conda-lock.yml +version: 1 +metadata: + content_hash: + linux-64: 98d89e0c307597f453c1f35dc51c3869775184b699c30c8a4d314510e150dced + channels: + - url: conda-forge + used_env_vars: [] + platforms: + - linux-64 + sources: + - environment.yml +package: +- name: _libgcc_mutex + version: '0.1' + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 + hash: + md5: d7c89558ba9fa0495403155b64376d81 + sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726 + category: main + optional: false +- name: ca-certificates + version: 2023.7.22 + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2023.7.22-hbcca054_0.conda + hash: + md5: a73ecd2988327ad4c8f2c331482917f2 + sha256: 525b7b6b5135b952ec1808de84e5eca57c7c7ff144e29ef3e96ae4040ff432c1 + category: main + optional: false +- name: ld_impl_linux-64 + version: '2.40' + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h41732ed_0.conda + hash: + md5: 7aca3059a1729aa76c597603f10b0dd3 + sha256: f6cc89d887555912d6c61b295d398cff9ec982a3417d38025c45d5dd9b9e79cd + category: main + optional: false +- name: libstdcxx-ng + version: 13.2.0 + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-h7e041cc_2.conda + hash: + md5: 9172c297304f2a20134fc56c97fbe229 + sha256: ab22ecdc974cdbe148874ea876d9c564294d5eafa760f403ed4fd495307b4243 + category: main + optional: false +- name: python_abi + version: '3.11' + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.11-4_cp311.conda + hash: + md5: d786502c97404c94d7d58d258a445a65 + sha256: 0be3ac1bf852d64f553220c7e6457e9c047dfb7412da9d22fbaa67e60858b3cf + category: main + optional: false +- name: tzdata + version: 2023c + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/tzdata-2023c-h71feb2d_0.conda + hash: + md5: 939e3e74d8be4dac89ce83b20de2492a + sha256: 0449138224adfa125b220154408419ec37c06b0b49f63c5954724325903ecf55 + category: main + optional: false +- name: libgomp + version: 13.2.0 + manager: conda + platform: linux-64 + dependencies: + _libgcc_mutex: '0.1' + url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h807b86a_2.conda + hash: + md5: e2042154faafe61969556f28bade94b9 + sha256: e1e82348f8296abfe344162b3b5f0ddc2f504759ebeb8b337ba99beaae583b15 + category: main + optional: false +- name: _openmp_mutex + version: '4.5' + manager: conda + platform: linux-64 + dependencies: + _libgcc_mutex: '0.1' + libgomp: '>=7.5.0' + url: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 + hash: + md5: 73aaf86a425cc6e73fcf236a5a46396d + sha256: fbe2c5e56a653bebb982eda4876a9178aedfc2b545f25d0ce9c4c0b508253d22 + category: main + optional: false +- name: libgcc-ng + version: 13.2.0 + manager: conda + platform: linux-64 + dependencies: + _libgcc_mutex: '0.1' + _openmp_mutex: '>=4.5' + url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h807b86a_2.conda + hash: + md5: c28003b0be0494f9a7664389146716ff + sha256: d361d3c87c376642b99c1fc25cddec4b9905d3d9b9203c1c545b8c8c1b04539a + category: main + optional: false +- name: bzip2 + version: 1.0.8 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h7f98852_4.tar.bz2 + hash: + md5: a1fd65c7ccbf10880423d82bca54eb54 + sha256: cb521319804640ff2ad6a9f118d972ed76d86bea44e5626c09a13d38f562e1fa + category: main + optional: false +- name: lerc + version: 4.0.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h27087fc_0.tar.bz2 + hash: + md5: 76bbff344f0134279f225174e9064c8f + sha256: cb55f36dcd898203927133280ae1dc643368af041a48bcf7c026acb7c47b0c12 + category: main + optional: false +- name: libdeflate + version: '1.19' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.19-hd590300_0.conda + hash: + md5: 1635570038840ee3f9c71d22aa5b8b6d + sha256: 985ad27aa0ba7aad82afa88a8ede6a1aacb0aaca950d710f15d85360451e72fd + category: main + optional: false +- name: libexpat + version: 2.5.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.5.0-hcb278e6_1.conda + hash: + md5: 6305a3dd2752c76335295da4e581f2fd + sha256: 74c98a563777ae2ad71f1f74d458a8ab043cee4a513467c159ccf159d0e461f3 + category: main + optional: false +- name: libffi + version: 3.4.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.4.0' + url: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 + hash: + md5: d645c6d2ac96843a2bfaccd2d62b3ac3 + sha256: ab6e9856c21709b7b517e940ae7028ae0737546122f83c2aa5d692860c3b149e + category: main + optional: false +- name: libjpeg-turbo + version: 3.0.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.0.0-hd590300_1.conda + hash: + md5: ea25936bb4080d843790b586850f82b8 + sha256: b954e09b7e49c2f2433d6f3bb73868eda5e378278b0f8c1dd10a7ef090e14f2f + category: main + optional: false +- name: libnsl + version: 2.0.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.0-hd590300_1.conda + hash: + md5: 854e3e1623b39777140f199c5f9ab952 + sha256: c0a0c0abc1c17983168c3239d79a62d53c424bc5dd1764dbcd0fa953d6fce5e0 + category: main + optional: false +- name: libuuid + version: 2.38.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda + hash: + md5: 40b61aab5c7ba9ff276c41cfffe6b80b + sha256: 787eb542f055a2b3de553614b25f09eefb0a0931b0c87dbcce6efdfd92f04f18 + category: main + optional: false +- name: libwebp-base + version: 1.3.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.3.2-hd590300_0.conda + hash: + md5: 30de3fd9b3b602f7473f30e684eeea8c + sha256: 68764a760fa81ef35dacb067fe8ace452bbb41476536a4a147a1051df29525f0 + category: main + optional: false +- name: libzlib + version: 1.2.13 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda + hash: + md5: f36c115f1ee199da648e0597ec2047ad + sha256: 370c7c5893b737596fd6ca0d9190c9715d89d888b8c88537ae1ef168c25e82e4 + category: main + optional: false +- name: ncurses + version: '6.4' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4-hcb278e6_0.conda + hash: + md5: 681105bccc2a3f7f1a837d47d39c9179 + sha256: ccf61e61d58a8a7b2d66822d5568e2dc9387883dd9b2da61e1d787ece4c4979a + category: main + optional: false +- name: openssl + version: 3.1.3 + manager: conda + platform: linux-64 + dependencies: + ca-certificates: '' + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.1.3-hd590300_0.conda + hash: + md5: 7bb88ce04c8deb9f7d763ae04a1da72f + sha256: f4e35f506c7e8ab7dfdc47255b0d5aa8ce0c99028ae0affafd274333042c4f70 + category: main + optional: false +- name: pthread-stubs + version: '0.4' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=7.5.0' + url: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-h36c2ea0_1001.tar.bz2 + hash: + md5: 22dad4df6e8630e8dff2428f6f6a7036 + sha256: 67c84822f87b641d89df09758da498b2d4558d47b920fd1d3fe6d3a871e000ff + category: main + optional: false +- name: xorg-libxau + version: 1.0.11 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.11-hd590300_0.conda + hash: + md5: 2c80dc38fface310c9bd81b17037fee5 + sha256: 309751371d525ce50af7c87811b435c176915239fc9e132b99a25d5e1703f2d4 + category: main + optional: false +- name: xorg-libxdmcp + version: 1.1.3 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.3-h7f98852_0.tar.bz2 + hash: + md5: be93aabceefa2fac576e971aef407908 + sha256: 4df7c5ee11b8686d3453e7f3f4aa20ceef441262b49860733066c52cfd0e4a77 + category: main + optional: false +- name: xz + version: 5.2.6 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 + hash: + md5: 2161070d867d1b1204ea749c8eec4ef0 + sha256: 03a6d28ded42af8a347345f82f3eebdd6807a08526d47899a42d62d319609162 + category: main + optional: false +- name: yaml + version: 0.2.5 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.4.0' + url: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2 + hash: + md5: 4cb3ad778ec2d5a7acbdf254eb1c42ae + sha256: a4e34c710eeb26945bdbdaba82d3d74f60a78f54a874ec10d373811a5d217535 + category: main + optional: false +- name: libpng + version: 1.6.39 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.39-h753d276_0.conda + hash: + md5: e1c890aebdebbfbf87e2c917187b4416 + sha256: a32b36d34e4f2490b99bddbc77d01a674d304f667f0e62c89e02c961addef462 + category: main + optional: false +- name: libsqlite + version: 3.43.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.43.0-h2797004_0.conda + hash: + md5: 903fa782a9067d5934210df6d79220f6 + sha256: e715fab7ec6b3f3df2a5962ef372ff0f871d215fe819482dcd80357999513652 + category: main + optional: false +- name: libxcb + version: '1.15' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + pthread-stubs: '' + xorg-libxau: '' + xorg-libxdmcp: '' + url: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.15-h0b41bf4_0.conda + hash: + md5: 33277193f5b92bad9fdd230eb700929c + sha256: a670902f0a3173a466c058d2ac22ca1dd0df0453d3a80e0212815c20a16b0485 + category: main + optional: false +- name: readline + version: '8.2' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + ncurses: '>=6.3,<7.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda + hash: + md5: 47d31b792659ce70f470b5c82fdfb7a4 + sha256: 5435cf39d039387fbdc977b0a762357ea909a7694d9528ab40f005e9208744d7 + category: main + optional: false +- name: tk + version: 8.6.13 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-h2797004_0.conda + hash: + md5: 513336054f884f95d9fd925748f41ef3 + sha256: 679e944eb93fde45d0963a22598fafacbb429bb9e7ee26009ba81c4e0c435055 + category: main + optional: false +- name: zstd + version: 1.5.5 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.5-hfc55251_0.conda + hash: + md5: 04b88013080254850d6c01ed54810589 + sha256: 607cbeb1a533be98ba96cf5cdf0ddbb101c78019f1fda063261871dad6248609 + category: main + optional: false +- name: freetype + version: 2.12.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libpng: '>=1.6.39,<1.7.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda + hash: + md5: 9ae35c3d96db2c94ce0cef86efdfa2cb + sha256: b2e3c449ec9d907dd4656cb0dc93e140f447175b125a3824b31368b06c666bb6 + category: main + optional: false +- name: libtiff + version: 4.6.0 + manager: conda + platform: linux-64 + dependencies: + lerc: '>=4.0.0,<5.0a0' + libdeflate: '>=1.19,<1.20.0a0' + libgcc-ng: '>=12' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libstdcxx-ng: '>=12' + libwebp-base: '>=1.3.2,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + xz: '>=5.2.6,<6.0a0' + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-ha9c0a0a_2.conda + hash: + md5: 55ed21669b2015f77c180feb1dd41930 + sha256: 45158f5fbee7ee3e257e6b9f51b9f1c919ed5518a94a9973fe7fa4764330473e + category: main + optional: false +- name: python + version: 3.11.6 + manager: conda + platform: linux-64 + dependencies: + bzip2: '>=1.0.8,<2.0a0' + ld_impl_linux-64: '>=2.36.1' + libexpat: '>=2.5.0,<3.0a0' + libffi: '>=3.4,<4.0a0' + libgcc-ng: '>=12' + libnsl: '>=2.0.0,<2.1.0a0' + libsqlite: '>=3.43.0,<4.0a0' + libuuid: '>=2.38.1,<3.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + ncurses: '>=6.4,<7.0a0' + openssl: '>=3.1.3,<4.0a0' + readline: '>=8.2,<9.0a0' + tk: '>=8.6.13,<8.7.0a0' + tzdata: '' + xz: '>=5.2.6,<6.0a0' + pip: '' + url: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.6-hab00c5b_0_cpython.conda + hash: + md5: b0dfbe2fcbfdb097d321bfd50ecddab1 + sha256: 84f13bd70cff5dcdaee19263b2d4291d5793856a718efc1b63a9cfa9eb6e2ca1 + category: main + optional: false +- name: attrs + version: 23.1.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/attrs-23.1.0-pyh71513ae_1.conda + hash: + md5: 3edfead7cedd1ab4400a6c588f3e75f8 + sha256: 063639cd568f5c7a557b0fb1cc27f098598c0d8ff869088bfeb82934674f8821 + category: main + optional: false +- name: brotli-python + version: 1.1.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + python: '>=3.11,<3.12.0a0' + python_abi: 3.11.* + url: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py311hb755f60_1.conda + hash: + md5: cce9e7c3f1c307f2a5fb08a2922d6164 + sha256: 559093679e9fdb6061b7b80ca0f9a31fe6ffc213f1dae65bc5c82e2cd1a94107 + category: main + optional: false +- name: certifi + version: 2023.7.22 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/certifi-2023.7.22-pyhd8ed1ab_0.conda + hash: + md5: 7f3dbc9179b4dde7da98dfb151d0ad22 + sha256: db66e31866ff4250c190788769e3a8a1709237c3e9c38d7143aae95ab75fcb31 + category: main + optional: false +- name: charset-normalizer + version: 3.3.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.0-pyhd8ed1ab_0.conda + hash: + md5: fef8ef5f0a54546b9efee39468229917 + sha256: 3407cd21af7e85aeb9499c377e7db25d2bbb9cbaf2f47d92626b3471dca65b4c + category: main + optional: false +- name: colorama + version: 0.4.6 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 3faab06a954c2a04039983f2c4a50d99 + sha256: 2c1b2e9755ce3102bca8d69e8f26e4f087ece73f50418186aee7c74bef8e1698 + category: main + optional: false +- name: defusedxml + version: 0.7.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 961b3a227b437d82ad7054484cfa71b2 + sha256: 9717a059677553562a8f38ff07f3b9f61727bd614f505658b0a5ecbcf8df89be + category: main + optional: false +- name: idna + version: '3.4' + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/idna-3.4-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 34272b248891bddccc64479f9a7fffed + sha256: 9887c35c374ec1847f167292d3fde023cb4c994a4ceeec283072b95440131f09 + category: main + optional: false +- name: lcms2 + version: '2.15' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.15-hb7c19ff_3.conda + hash: + md5: e96637dd92c5f340215c753a5c9a22d7 + sha256: cc0b2ddab52b20698b26fe8622ebe37e0d462d8691a1f324e7b00f7d904765e3 + category: main + optional: false +- name: markupsafe + version: 2.1.3 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.11,<3.12.0a0' + python_abi: 3.11.* + url: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-2.1.3-py311h459d7ec_1.conda + hash: + md5: 71120b5155a0c500826cf81536721a15 + sha256: e1a9930f35e39bf65bc293e24160b83ebf9f800f02749f65358e1c04882ee6b0 + category: main + optional: false +- name: openjpeg + version: 2.5.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libpng: '>=1.6.39,<1.7.0a0' + libstdcxx-ng: '>=12' + libtiff: '>=4.6.0,<4.7.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.0-h488ebb8_3.conda + hash: + md5: 128c25b7fe6a25286a48f3a6a9b5b6f3 + sha256: 9fe91b67289267de68fda485975bb48f0605ac503414dc663b50d8b5f29bc82a + category: main + optional: false +- name: pkgutil-resolve-name + version: 1.3.10 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_1.conda + hash: + md5: 405678b942f2481cecdb3e010f4925d9 + sha256: fecf95377134b0e8944762d92ecf7b0149c07d8186fb5db583125a2705c7ea0a + category: main + optional: false +- name: pycparser + version: '2.21' + manager: conda + platform: linux-64 + dependencies: + python: 2.7.*|>=3.4 + url: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.21-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 076becd9e05608f8dc72757d5f3a91ff + sha256: 74c63fd03f1f1ea2b54e8bc529fd1a600aaafb24027b738d0db87909ee3a33dc + category: main + optional: false +- name: pysocks + version: 1.7.1 + manager: conda + platform: linux-64 + dependencies: + __unix: '' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2 + hash: + md5: 2a7de29fb590ca14b5243c4c812c8025 + sha256: a42f826e958a8d22e65b3394f437af7332610e43ee313393d1cf143f0a2d274b + category: main + optional: false +- name: python-fastjsonschema + version: 2.18.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.3' + url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.18.1-pyhd8ed1ab_0.conda + hash: + md5: 305141cff54af2f90e089d868fffce28 + sha256: 3fb1af1ac7525072c46e111bc4e96ddf971f792ab049ca3aa25dbebbaffb6f7d + category: main + optional: false +- name: pytz + version: 2023.3.post1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/pytz-2023.3.post1-pyhd8ed1ab_0.conda + hash: + md5: c93346b446cd08c169d843ae5fc0da97 + sha256: 6b680e63d69aaf087cd43ca765a23838723ef59b0a328799e6363eb13f52c49e + category: main + optional: false +- name: pyyaml + version: 6.0.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.11,<3.12.0a0' + python_abi: 3.11.* + yaml: '>=0.2.5,<0.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.1-py311h459d7ec_1.conda + hash: + md5: 52719a74ad130de8fb5d047dc91f247a + sha256: 28729ef1ffa7f6f9dfd54345a47c7faac5d34296d66a2b9891fb147f4efe1348 + category: main + optional: false +- name: rpds-py + version: 0.10.3 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.11,<3.12.0a0' + python_abi: 3.11.* + url: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.10.3-py311h46250e7_1.conda + hash: + md5: 7f5b917bca99c5b9d8b4c692e15eb1a3 + sha256: 998b5029ff62fa7a854c6c4985e86c4b29cb41003135fac811995b412988cdf0 + category: main + optional: false +- name: ruamel_yaml + version: 0.15.80 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.11,<3.12.0a0' + python_abi: 3.11.* + yaml: '>=0.2.5,<0.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/ruamel_yaml-0.15.80-py311h459d7ec_1009.conda + hash: + md5: 799197f6c21be0b366d1a593d1015a5c + sha256: 3bc1ee8e536710a4c4cb38dee98923ade62def7dc92fb646de6df01b913c1ae8 + category: main + optional: false +- name: setuptools + version: 68.2.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-68.2.2-pyhd8ed1ab_0.conda + hash: + md5: fc2166155db840c634a1291a5c35a709 + sha256: 851901b1f8f2049edb36a675f0c3f9a98e1495ef4eb214761b048c6f696a06f7 + category: main + optional: false +- name: six + version: 1.16.0 + manager: conda + platform: linux-64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2 + hash: + md5: e5f25f8dbc060e9a8d912e432202afc2 + sha256: a85c38227b446f42c5b90d9b642f2c0567880c15d72492d8da074a59c8f91dd6 + category: main + optional: false +- name: tornado + version: 6.3.3 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.11,<3.12.0a0' + python_abi: 3.11.* + url: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.3.3-py311h459d7ec_1.conda + hash: + md5: a700fcb5cedd3e72d0c75d095c7a6eda + sha256: 3f0640415c6f50c6b31b5ce41a870ac48c130fda8921aae11afea84c54a6ba84 + category: main + optional: false +- name: traitlets + version: 5.11.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.11.2-pyhd8ed1ab_0.conda + hash: + md5: bd3f90f7551e1cffb1f402880eb2cef1 + sha256: 81f2675ebc2bd6016c304770c81812aab8947953b0f0cca766077b127cc7e8f1 + category: main + optional: false +- name: typing_extensions + version: 4.8.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.8.0-pyha770c72_0.conda + hash: + md5: 5b1be40a26d10a06f6d4f1f9e19fa0c7 + sha256: 38d16b5c53ec1af845d37d22e7bb0e6c934c7f19499123507c5a470f6f8b7dde + category: main + optional: false +- name: wheel + version: 0.41.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.41.2-pyhd8ed1ab_0.conda + hash: + md5: 1ccd092478b3e0ee10d7a891adbf8a4f + sha256: 21bcec5373b04d739ab65252b5532b04a08d229865ebb24b5b94902d6d0a77b0 + category: main + optional: false +- name: zipp + version: 3.17.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda + hash: + md5: 2e4d6bc0b14e10f895fc6791a7d9b26a + sha256: bced1423fdbf77bca0a735187d05d9b9812d2163f60ab426fc10f11f92ecbe26 + category: main + optional: false +- name: cffi + version: 1.16.0 + manager: conda + platform: linux-64 + dependencies: + libffi: '>=3.4,<4.0a0' + libgcc-ng: '>=12' + pycparser: '' + python: '>=3.11,<3.12.0a0' + python_abi: 3.11.* + url: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.16.0-py311hb3a22ac_0.conda + hash: + md5: b3469563ac5e808b0cd92810d0697043 + sha256: b71c94528ca0c35133da4b7ef69b51a0b55eeee570376057f3d2ad60c3ab1444 + category: main + optional: false +- name: clyent + version: 1.2.2 + manager: conda + platform: linux-64 + dependencies: + python: '' + setuptools: '' + url: https://conda.anaconda.org/conda-forge/noarch/clyent-1.2.2-py_1.tar.bz2 + hash: + md5: b9ee3fdf59f49883497741509ea364b6 + sha256: 2521c43e0e481ad543baa0bb9289aff2bb242d5304eed11f17ca45943300ae62 + category: main + optional: false +- name: conda-pack + version: 0.7.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + setuptools: '' + url: https://conda.anaconda.org/conda-forge/noarch/conda-pack-0.7.1-pyhd8ed1ab_0.conda + hash: + md5: 70f87fd416397056d23f1a0f71487c87 + sha256: 29cd54de8336ed588e80012483e20291a29b72fd629b267da348ba0b06071639 + category: main + optional: false +- name: importlib_resources + version: 6.1.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + zipp: '>=3.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.1.0-pyhd8ed1ab_0.conda + hash: + md5: 48b0d98e0c0ec810d3ccc2a0926c8c0e + sha256: adab6da633ec3b642f036ab5c1196c3e2db0e8db57fb0c7fc9a8e06e29fa9bdc + category: main + optional: false +- name: jinja2 + version: 3.1.2 + manager: conda + platform: linux-64 + dependencies: + markupsafe: '>=2.0' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.2-pyhd8ed1ab_1.tar.bz2 + hash: + md5: c8490ed5c70966d232fdd389d0dbed37 + sha256: b045faba7130ab263db6a8fdc96b1a3de5fcf85c4a607c5f11a49e76851500b5 + category: main + optional: false +- name: pillow + version: 10.0.1 + manager: conda + platform: linux-64 + dependencies: + freetype: '>=2.12.1,<3.0a0' + lcms2: '>=2.15,<3.0a0' + libgcc-ng: '>=12' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + libwebp-base: '>=1.3.2,<2.0a0' + libxcb: '>=1.15,<1.16.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + openjpeg: '>=2.5.0,<3.0a0' + python: '>=3.11,<3.12.0a0' + python_abi: 3.11.* + tk: '>=8.6.13,<8.7.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/pillow-10.0.1-py311ha6c5da5_2.conda + hash: + md5: d6de249502f16ac151fcef9f743937b9 + sha256: f6359ecfe2fb1fc79f83dafa42b776734bbc3cb5c4f8ccaa3a838813fbb19bd2 + category: main + optional: false +- name: pip + version: 23.2.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + setuptools: '' + wheel: '' + url: https://conda.anaconda.org/conda-forge/noarch/pip-23.2.1-pyhd8ed1ab_0.conda + hash: + md5: e2783aa3f9235225eec92f9081c5b801 + sha256: 9e401b171856e12f6aa32ae5cc1ae1d3708aa7d705ddf359ee7dd0dffd73c2b5 + category: main + optional: false +- name: python-dateutil + version: 2.8.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + six: '>=1.5' + url: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.8.2-pyhd8ed1ab_0.tar.bz2 + hash: + md5: dd999d1cc9f79e67dbb855c8924c7984 + sha256: 54d7785c7678166aa45adeaccfc1d2b8c3c799ca2dc05d4a82bb39b1968bd7da + category: main + optional: false +- name: referencing + version: 0.30.2 + manager: conda + platform: linux-64 + dependencies: + attrs: '>=22.2.0' + python: '>=3.8' + rpds-py: '>=0.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/referencing-0.30.2-pyhd8ed1ab_0.conda + hash: + md5: a33161b983172ba6ef69d5fc850650cd + sha256: a6768fabc12f1eed87fec68c5c65439e908655cded1e458d70a164abbce13287 + category: main + optional: false +- name: tqdm + version: 4.66.1 + manager: conda + platform: linux-64 + dependencies: + colorama: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.1-pyhd8ed1ab_0.conda + hash: + md5: 03c97908b976498dcae97eb4e4f3149c + sha256: b61c9222af05e8c5ff27e4a4d2eb81870c21ffd7478346be3ef644b7a3759cc4 + category: main + optional: false +- name: typing-extensions + version: 4.8.0 + manager: conda + platform: linux-64 + dependencies: + typing_extensions: 4.8.0 + url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.8.0-hd8ed1ab_0.conda + hash: + md5: 384462e63262a527bda564fa2d9126c0 + sha256: d6e1dddd0c372218ef15912383d351ac8c73465cbf16238017f0269813cafe2d + category: main + optional: false +- name: urllib3 + version: 2.0.6 + manager: conda + platform: linux-64 + dependencies: + brotli-python: '>=1.0.9' + pysocks: '>=1.5.6,<2.0,!=1.5.7' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.0.6-pyhd8ed1ab_0.conda + hash: + md5: d5f8944ff9ab24a292511c83dce33dea + sha256: b93db71eb710ae712f1dcb7fb9ea28d03b75841ec42510f7d578956ba6fb6dd5 + category: main + optional: false +- name: jsonschema-specifications + version: 2023.7.1 + manager: conda + platform: linux-64 + dependencies: + importlib_resources: '>=1.4.0' + python: '>=3.8' + referencing: '>=0.25.0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.7.1-pyhd8ed1ab_0.conda + hash: + md5: 7c27ea1bdbe520bb830dcadd59f55cbf + sha256: 7b0061e106674f27cc718f79a095e90a5667a3635ec6626dd23b3be0fd2bfbdc + category: main + optional: false +- name: platformdirs + version: 3.11.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + typing-extensions: '>=4.6.3' + url: https://conda.anaconda.org/conda-forge/noarch/platformdirs-3.11.0-pyhd8ed1ab_0.conda + hash: + md5: 8f567c0a74aa44cf732f15773b4083b0 + sha256: b3d809ff5a18ee8514bba8bc05a23b4cdf1758090a18a2cf742af38aed405144 + category: main + optional: false +- name: requests + version: 2.31.0 + manager: conda + platform: linux-64 + dependencies: + certifi: '>=2017.4.17' + charset-normalizer: '>=2,<4' + idna: '>=2.5,<4' + python: '>=3.7' + urllib3: '>=1.21.1,<3' + url: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + hash: + md5: a30144e4156cdbb236f99ebb49828f8b + sha256: 9f629d6fd3c8ac5f2a198639fe7af87c4db2ac9235279164bfe0fcb49d8c4bad + category: main + optional: false +- name: zstandard + version: 0.21.0 + manager: conda + platform: linux-64 + dependencies: + cffi: '>=1.11' + libgcc-ng: '>=12' + python: '>=3.11,<3.12.0a0' + python_abi: 3.11.* + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.21.0-py311haa97af0_1.conda + hash: + md5: 780c131e9c40cd78194f21bfd9b13c22 + sha256: 2d582e91c781692a2aa884ef6693f18c11374963ce77901143ccd4ec29f6b207 + category: main + optional: false +- name: conda-package-streaming + version: 0.9.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + zstandard: '>=0.15' + url: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.9.0-pyhd8ed1ab_0.conda + hash: + md5: 38253361efb303deead3eab39ae9269b + sha256: 654a2488f77bf43555787d952dbffdc5d97956ff4aa9e0414a7131bb741dcf4c + category: main + optional: false +- name: jsonschema + version: 4.19.1 + manager: conda + platform: linux-64 + dependencies: + attrs: '>=22.2.0' + importlib_resources: '>=1.4.0' + jsonschema-specifications: '>=2023.03.6' + pkgutil-resolve-name: '>=1.3.10' + python: '>=3.8' + referencing: '>=0.28.4' + rpds-py: '>=0.7.1' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.19.1-pyhd8ed1ab_0.conda + hash: + md5: 78aff5d2af74e6537c1ca73017f01f4f + sha256: b4e50e1d53b984a467e79b7ba69cc408d14e3a2002cad4eaf7798e20268cff2d + category: main + optional: false +- name: jupyter_core + version: 5.3.2 + manager: conda + platform: linux-64 + dependencies: + platformdirs: '>=2.5' + python: '>=3.11,<3.12.0a0' + python_abi: 3.11.* + traitlets: '>=5.3' + url: https://conda.anaconda.org/conda-forge/linux-64/jupyter_core-5.3.2-py311h38be061_0.conda + hash: + md5: 4e4341e940c0dfa1038c1a2d11fd8c3e + sha256: 189435dc967fb5a83f7855abadc6ea503a7f242cbbb1d21c8785b375cfe967ae + category: main + optional: false +- name: requests-toolbelt + version: 1.0.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + requests: '>=2.0.1,<3.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda + hash: + md5: 99c98318c8646b08cc764f90ce98906e + sha256: 20eaefc5dba74ff6c31e537533dde59b5b20f69e74df49dff19d43be59785fa3 + category: main + optional: false +- name: conda-package-handling + version: 2.2.0 + manager: conda + platform: linux-64 + dependencies: + conda-package-streaming: '>=0.9.0' + python: '>=3.7' + zstandard: '>=0.15' + url: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.2.0-pyh38be061_0.conda + hash: + md5: 8a3ae7f6318376aa08ea753367bb7dd6 + sha256: 9a221808405d813d8c555efce6944379b907d36d79e77d526d573efa6b996d26 + category: main + optional: false +- name: nbformat + version: 5.9.2 + manager: conda + platform: linux-64 + dependencies: + jsonschema: '>=2.6' + jupyter_core: '' + python: '>=3.8' + python-fastjsonschema: '' + traitlets: '>=5.1' + url: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.9.2-pyhd8ed1ab_0.conda + hash: + md5: 61ba076de6530d9301a0053b02f093d2 + sha256: fc82c5a9116820757b03ffb836b36f0f50e4cd390018024dbadb0ee0217f6992 + category: main + optional: false +- name: anaconda-client + version: 1.12.1 + manager: conda + platform: linux-64 + dependencies: + anaconda-project: '>=0.9.1' + clyent: '>=1.2.0' + conda-package-handling: '>=1.7.3' + defusedxml: '>=0.7.1' + nbformat: '>=4.4.0' + pillow: '>=8.2' + python: '>=3.8' + python-dateutil: '>=2.6.1' + pytz: '>=2021.3' + pyyaml: '>=3.12' + requests: '>=2.20.0' + requests-toolbelt: '>=0.9.1' + setuptools: '>=58.0.4' + six: '>=1.15.0' + tqdm: '>=4.56.0' + urllib3: '>=1.26.4' + url: https://conda.anaconda.org/conda-forge/noarch/anaconda-client-1.12.1-pyhd8ed1ab_1.conda + hash: + md5: 556df5f70fb0f251e809bbc7af49eecc + sha256: 1accf2eeaa4a28a22923c5d708779ade747c859dcee1746af393fc4e952d121b + category: main + optional: false +- name: anaconda-project + version: 0.11.1 + manager: conda + platform: linux-64 + dependencies: + anaconda-client: '' + conda-pack: '' + jinja2: '' + python: '>=3.6' + requests: '' + ruamel_yaml: '' + tornado: '>=4.2' + tqdm: '' + url: https://conda.anaconda.org/conda-forge/noarch/anaconda-project-0.11.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 85406089db6aa63ee45da8e9f0b966b6 + sha256: 5025ff5066e4a8765ca35bb4f6145f188b249634090236c8beb25f3fb5ed4874 + category: main + optional: false diff --git a/environment.yml b/environment.yml new file mode 100644 index 0000000..8dd12ba --- /dev/null +++ b/environment.yml @@ -0,0 +1,6 @@ +name: upload-nightly-action +channels: + - conda-forge +dependencies: + - python=3.11 + - anaconda-client==1.12.1 diff --git a/lock.sh b/lock.sh new file mode 100644 index 0000000..afb90d0 --- /dev/null +++ b/lock.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# This should be the base image the Docker image built by the GitHub Action uses +BUILD_IMAGE="mambaorg/micromamba:1.4.9-bullseye-slim" +docker pull "${BUILD_IMAGE}" + +# Don't need to ensure emulation possible on non-x86_64 platforms at the +# `docker run` level as the platform is specified in the conda-lock command. +docker run \ + --rm \ + --volume "${PWD}":/work \ + --workdir /work \ + "${BUILD_IMAGE}" \ + /bin/bash -c "\ + micromamba install --yes --channel conda-forge conda-lock && \ + conda-lock lock --micromamba --platform linux-64 --file environment.yml"