From 75d4479969766b9b361c48966ee06ff12824076f Mon Sep 17 00:00:00 2001 From: Kasper Thystrup Karstensen Date: Mon, 3 Aug 2026 14:15:22 +0200 Subject: [PATCH 1/7] Add automated PyPI publish and Bioconda update workflow This workflow automates the process of publishing a Python package to PyPI and updating the corresponding Bioconda recipe. It includes steps for checking out the code, setting up Python, building the package, and handling versioning and SHA256 hash retrieval. Created with Gemini-flash --- .github/workflows/PUBLISH.yml | 113 ++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 .github/workflows/PUBLISH.yml diff --git a/.github/workflows/PUBLISH.yml b/.github/workflows/PUBLISH.yml new file mode 100644 index 0000000..1240a9b --- /dev/null +++ b/.github/workflows/PUBLISH.yml @@ -0,0 +1,113 @@ +name: Publish to PyPi and Bioconda + +on: + release: + types: [published] + workflow_dispatch: + inputs: + version: + description: 'Version string (e.g., 1.2.3)' + required: true + +jobs: + pypi-publish: + name: Build & Publish to PyPI + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/MMASeq + permissions: + contents: read + id-token: write # Required for PyPI Trusted Publishing (OIDC) + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install build tool + run: python -m pip install build --user + + - name: Build sdist and wheel + run: python -m build + + - name: Publish package to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + + bioconda-update: + name: Update Bioconda Recipe & Open PR + needs: pypi-publish + runs-on: ubuntu-latest + + steps: + - name: Wait 5 minutes for PyPI indexing + run: | + echo "Waiting 5 minutes to ensure PyPI indexing and sha256 generation..." + sleep 300 + + - name: Extract Tag / Version + id: get_version + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + VERSION="${{ github.event.inputs.version }}" + else + # Strip 'v' prefix if present (e.g., v1.0.0 -> 1.0.0) + VERSION="${GITHUB_REF_NAME#v}" + fi + echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT + + - name: Fetch PyPI SHA256 Hash + id: fetch_hash + run: | + VERSION="${{ steps.get_version.outputs.VERSION }}" + JSON=$(curl -s "https://pypi.org/pypi/MMASeq/${VERSION}/json") + SHA256=$(echo "$JSON" | jq -r '.urls[] | select(.packagetype=="sdist") | .digests.sha256') + + if [ -z "$SHA256" ] || [ "$SHA256" = "null" ]; then + echo "Error: Could not retrieve sha256 from PyPI for version ${VERSION}" + exit 1 + fi + + echo "SHA256=${SHA256}" >> $GITHUB_OUTPUT + + # 1. Checkout your FORK of bioconda-recipes + - name: Checkout ssi-dk/bioconda-recipes Fork + uses: actions/checkout@v4 + with: + repository: 'ssi-dk/bioconda-recipes' + token: ${{ secrets.BIOCONDA_TOKEN }} + path: bioconda-recipes + + # 2. Modify meta.yaml inside the checked out fork + - name: Update meta.yaml + run: | + cd bioconda-recipes/recipes/mmaseq + VERSION="${{ steps.get_version.outputs.VERSION }}" + SHA256="${{ steps.fetch_hash.outputs.SHA256 }}" + + # Update version and sha256 in meta.yaml + sed -i -E "s/{% set version = \".*\" %}/{% set version = \"${VERSION}\" %}/g" meta.yaml + sed -i -E "s/sha256: .*/sha256: ${SHA256}/g" meta.yaml + + # 3. Create PR against bioconda/bioconda-recipes + - name: Create Pull Request to Bioconda + uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.BIOCONDA_TOKEN }} + path: bioconda-recipes + commit-message: "mmaseq: bump version to ${{ steps.get_version.outputs.VERSION }}" + title: "mmaseq: bump to version ${{ steps.get_version.outputs.VERSION }}" + body: | + Automated update for package `mmaseq` to version `${{ steps.get_version.outputs.VERSION }}`. + + - **Package:** `mmaseq` + - **Version:** `${{ steps.get_version.outputs.VERSION }}` + - **Source SHA256:** `${{ steps.fetch_hash.outputs.SHA256 }}` + branch: "mmaseq-${{ steps.get_version.outputs.VERSION }}" + base: "master" # Target branch on bioconda/bioconda-recipes + # To target the master bioconda repo rather than the fork itself: + push-to-fork: "ssi-dk/bioconda-recipes" From 1e938f894dcdbdab992ed0be90e2865396b17884 Mon Sep 17 00:00:00 2001 From: Kasper Thystrup Karstensen Date: Mon, 3 Aug 2026 14:32:00 +0200 Subject: [PATCH 2/7] Added dry-run option which prints the bioconda meta file --- .github/workflows/PUBLISH.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/PUBLISH.yml b/.github/workflows/PUBLISH.yml index 1240a9b..9efd2ea 100644 --- a/.github/workflows/PUBLISH.yml +++ b/.github/workflows/PUBLISH.yml @@ -8,6 +8,10 @@ on: version: description: 'Version string (e.g., 1.2.3)' required: true + dry_run: + description: 'Dry Run (Skip PyPI publish and Bioconda PR)' + type: boolean + default: true jobs: pypi-publish: @@ -93,6 +97,13 @@ jobs: sed -i -E "s/{% set version = \".*\" %}/{% set version = \"${VERSION}\" %}/g" meta.yaml sed -i -E "s/sha256: .*/sha256: ${SHA256}/g" meta.yaml + - name: Preview updated meta.yaml + if: ${{ inputs.dry_run == true }} + run: | + echo "::group::Click to expand generated meta.yaml" + cat mock_recipe/meta.yaml + echo "::endgroup::" + # 3. Create PR against bioconda/bioconda-recipes - name: Create Pull Request to Bioconda uses: peter-evans/create-pull-request@v6 From 1244146c68cc00477cafb4ad79d0d9bd12f910ee Mon Sep 17 00:00:00 2001 From: Kasper Thystrup Karstensen Date: Mon, 3 Aug 2026 14:42:45 +0200 Subject: [PATCH 3/7] Add dry run mode for PyPI publishing and SHA256 fetch --- .github/workflows/PUBLISH.yml | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/.github/workflows/PUBLISH.yml b/.github/workflows/PUBLISH.yml index 9efd2ea..e2515f6 100644 --- a/.github/workflows/PUBLISH.yml +++ b/.github/workflows/PUBLISH.yml @@ -40,8 +40,15 @@ jobs: run: python -m build - name: Publish package to PyPI + if: ${{ inputs.dry_run != true }} uses: pypa/gh-action-pypi-publish@release/v1 - + + - name: Report Build Success + if: ${{ inputs.dry_run == true }} + run: | + echo "DRY RUN MODE: Package built successfully!" + ls -la dist/ + bioconda-update: name: Update Bioconda Recipe & Open PR needs: pypi-publish @@ -67,17 +74,16 @@ jobs: - name: Fetch PyPI SHA256 Hash id: fetch_hash run: | - VERSION="${{ steps.get_version.outputs.VERSION }}" - JSON=$(curl -s "https://pypi.org/pypi/MMASeq/${VERSION}/json") - SHA256=$(echo "$JSON" | jq -r '.urls[] | select(.packagetype=="sdist") | .digests.sha256') - - if [ -z "$SHA256" ] || [ "$SHA256" = "null" ]; then - echo "Error: Could not retrieve sha256 from PyPI for version ${VERSION}" - exit 1 + if [ "${{ inputs.dry_run }}" = "true" ]; then + echo "DRY RUN MODE: Generating fake sha256" + echo "SHA256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" >> $GITHUB_OUTPUT + else + VERSION="${{ steps.get_version.outputs.VERSION }}" + JSON=$(curl -s "https://pypi.org/pypi/MMASeq/${VERSION}/json") + SHA256=$(echo "$JSON" | jq -r '.urls[] | select(.packagetype=="sdist") | .digests.sha256') + echo "SHA256=${SHA256}" >> $GITHUB_OUTPUT fi - echo "SHA256=${SHA256}" >> $GITHUB_OUTPUT - # 1. Checkout your FORK of bioconda-recipes - name: Checkout ssi-dk/bioconda-recipes Fork uses: actions/checkout@v4 @@ -105,6 +111,14 @@ jobs: echo "::endgroup::" # 3. Create PR against bioconda/bioconda-recipes + - name: Check Token Presence + run: | + if [ -z "${{ secrets.BIOCONDA_TOKEN }}" ]; then + echo "WARNING: BIOCONDA_TOKEN secret is NOT set / has expired. Create a new token for the ssi-dk/bioconda-recipes in Profile settings > Credentials > Fine-grained personal access tokens.\nSkipping actual git push/PR creation." + else + echo "BIOCONDA_TOKEN secret is ready!" + fi + - name: Create Pull Request to Bioconda uses: peter-evans/create-pull-request@v6 with: From 0e77ede7d2b975e14d50c1229983a29a069c9c26 Mon Sep 17 00:00:00 2001 From: Kasper Thystrup Karstensen Date: Mon, 3 Aug 2026 14:52:51 +0200 Subject: [PATCH 4/7] temp Add pull_request trigger to PUBLISH workflow --- .github/workflows/PUBLISH.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/PUBLISH.yml b/.github/workflows/PUBLISH.yml index e2515f6..f71652b 100644 --- a/.github/workflows/PUBLISH.yml +++ b/.github/workflows/PUBLISH.yml @@ -1,6 +1,7 @@ name: Publish to PyPi and Bioconda on: + pull_request: release: types: [published] workflow_dispatch: From a1b8dec6e745d7f78cc994031bd014f30519d37e Mon Sep 17 00:00:00 2001 From: Kasper Thystrup Karstensen Date: Mon, 3 Aug 2026 14:57:04 +0200 Subject: [PATCH 5/7] Update PUBLISH.yml --- .github/workflows/PUBLISH.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/PUBLISH.yml b/.github/workflows/PUBLISH.yml index f71652b..e2515f6 100644 --- a/.github/workflows/PUBLISH.yml +++ b/.github/workflows/PUBLISH.yml @@ -1,7 +1,6 @@ name: Publish to PyPi and Bioconda on: - pull_request: release: types: [published] workflow_dispatch: From 4ddfc86b2ef219ace4e9eaa81708787e43093a41 Mon Sep 17 00:00:00 2001 From: Kasper Thystrup Karstensen Date: Mon, 3 Aug 2026 14:59:56 +0200 Subject: [PATCH 6/7] Refactor version assignment in PUBLISH.yml Updated version handling in workflow for better clarity during PRs and dry runs. --- .github/workflows/PUBLISH.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/PUBLISH.yml b/.github/workflows/PUBLISH.yml index e2515f6..22c55da 100644 --- a/.github/workflows/PUBLISH.yml +++ b/.github/workflows/PUBLISH.yml @@ -66,15 +66,16 @@ jobs: if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then VERSION="${{ github.event.inputs.version }}" else - # Strip 'v' prefix if present (e.g., v1.0.0 -> 1.0.0) - VERSION="${GITHUB_REF_NAME#v}" + # Fallback version for PR / automated tests + VERSION="1.0.0-test" fi echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT - name: Fetch PyPI SHA256 Hash id: fetch_hash run: | - if [ "${{ inputs.dry_run }}" = "true" ]; then + # If it's a pull request or dry_run is true, use a mock hash + if [ "${{ github.event_name }}" = "pull_request" ] || [ "${{ inputs.dry_run }}" = "true" ]; then echo "DRY RUN MODE: Generating fake sha256" echo "SHA256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" >> $GITHUB_OUTPUT else From 2ebf390f34e2eb7d3b346c647c47789618a65438 Mon Sep 17 00:00:00 2001 From: Kasper Thystrup Karstensen Date: Wed, 5 Aug 2026 15:51:30 +0200 Subject: [PATCH 7/7] Simplify PUBLISH workflow and remove unused steps Refactor workflow to simplify version extraction and PR creation. --- .github/workflows/PUBLISH.yml | 96 ++++++++++------------------------- 1 file changed, 27 insertions(+), 69 deletions(-) diff --git a/.github/workflows/PUBLISH.yml b/.github/workflows/PUBLISH.yml index 22c55da..054a128 100644 --- a/.github/workflows/PUBLISH.yml +++ b/.github/workflows/PUBLISH.yml @@ -60,80 +60,38 @@ jobs: echo "Waiting 5 minutes to ensure PyPI indexing and sha256 generation..." sleep 300 - - name: Extract Tag / Version - id: get_version - run: | - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - VERSION="${{ github.event.inputs.version }}" - else - # Fallback version for PR / automated tests - VERSION="1.0.0-test" - fi - echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT - - - name: Fetch PyPI SHA256 Hash - id: fetch_hash - run: | - # If it's a pull request or dry_run is true, use a mock hash - if [ "${{ github.event_name }}" = "pull_request" ] || [ "${{ inputs.dry_run }}" = "true" ]; then - echo "DRY RUN MODE: Generating fake sha256" - echo "SHA256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" >> $GITHUB_OUTPUT - else - VERSION="${{ steps.get_version.outputs.VERSION }}" - JSON=$(curl -s "https://pypi.org/pypi/MMASeq/${VERSION}/json") - SHA256=$(echo "$JSON" | jq -r '.urls[] | select(.packagetype=="sdist") | .digests.sha256') - echo "SHA256=${SHA256}" >> $GITHUB_OUTPUT - fi - - # 1. Checkout your FORK of bioconda-recipes - - name: Checkout ssi-dk/bioconda-recipes Fork + - name: Checkout bioconda-recipes fork uses: actions/checkout@v4 with: - repository: 'ssi-dk/bioconda-recipes' - token: ${{ secrets.BIOCONDA_TOKEN }} + repository: ssi-dk/bioconda-recipes + ref: master path: bioconda-recipes - # 2. Modify meta.yaml inside the checked out fork - - name: Update meta.yaml - run: | - cd bioconda-recipes/recipes/mmaseq - VERSION="${{ steps.get_version.outputs.VERSION }}" - SHA256="${{ steps.fetch_hash.outputs.SHA256 }}" - - # Update version and sha256 in meta.yaml - sed -i -E "s/{% set version = \".*\" %}/{% set version = \"${VERSION}\" %}/g" meta.yaml - sed -i -E "s/sha256: .*/sha256: ${SHA256}/g" meta.yaml + - name: Set up Miniconda + uses: conda-incubator/setup-miniconda@v3 + with: + auto-update-conda: true + activate-environment: bioconda-utils + environment-file: environment.yml + # If you don't want environment.yml, see next step for a pip/conda install approach - - name: Preview updated meta.yaml - if: ${{ inputs.dry_run == true }} + - name: Install bioconda-utils + shell: bash run: | - echo "::group::Click to expand generated meta.yaml" - cat mock_recipe/meta.yaml - echo "::endgroup::" + conda create -y -n bioconda-utils -c conda-forge -c bioconda --strict-channel-priority bioconda-utils + conda activate bioconda-utils + bioconda-utils --help - # 3. Create PR against bioconda/bioconda-recipes - - name: Check Token Presence + - name: Run autobump for MMASeq recipe + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.BIOCONDARECIPES }} run: | - if [ -z "${{ secrets.BIOCONDA_TOKEN }}" ]; then - echo "WARNING: BIOCONDA_TOKEN secret is NOT set / has expired. Create a new token for the ssi-dk/bioconda-recipes in Profile settings > Credentials > Fine-grained personal access tokens.\nSkipping actual git push/PR creation." - else - echo "BIOCONDA_TOKEN secret is ready!" - fi - - - name: Create Pull Request to Bioconda - uses: peter-evans/create-pull-request@v6 - with: - token: ${{ secrets.BIOCONDA_TOKEN }} - path: bioconda-recipes - commit-message: "mmaseq: bump version to ${{ steps.get_version.outputs.VERSION }}" - title: "mmaseq: bump to version ${{ steps.get_version.outputs.VERSION }}" - body: | - Automated update for package `mmaseq` to version `${{ steps.get_version.outputs.VERSION }}`. - - - **Package:** `mmaseq` - - **Version:** `${{ steps.get_version.outputs.VERSION }}` - - **Source SHA256:** `${{ steps.fetch_hash.outputs.SHA256 }}` - branch: "mmaseq-${{ steps.get_version.outputs.VERSION }}" - base: "master" # Target branch on bioconda/bioconda-recipes - # To target the master bioconda repo rather than the fork itself: - push-to-fork: "ssi-dk/bioconda-recipes" + conda activate bioconda-utils + cd bioconda-recipes + + # config.yml lives at the bioconda-recipes root + # recipes/ is the directory containing recipes + bioconda-utils autobump recipes/ config.yml \ + --packages mmaseq \ + --create-pr