Skip to content

Bump conda-forge feedstock #31

Bump conda-forge feedstock

Bump conda-forge feedstock #31

name: Bump conda-forge feedstock
on:
workflow_dispatch: {}
# auto-run when the PyPI publish workflow completes
workflow_run:
workflows: ["Upload BiaPy to PyPI"] # must match the other workflow's name
types: [completed]
permissions:
contents: write
pull-requests: write
env:
PACKAGE_NAME: biapy
GH_TOKEN: ${{ secrets.CF_GH_TOKEN }}
FEEDSTOCK_FORK: ${{ secrets.CF_FEEDSTOCK_FORK }}
# avoid overlapping bumps for the same workflow run
concurrency:
group: cf-bump-${{ github.workflow }}-${{ github.run_id }}
cancel-in-progress: false
jobs:
bump-feedstock:
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-latest
steps:
- name: Check out this repo
uses: actions/checkout@v4
- name: Determine version from release tag (fallback to PyPI latest on manual run)
id: ver
shell: bash
run: |
if [ "${{ github.event_name }}" = "release" ]; then
RAW_TAG="${{ github.event.release.tag_name }}"
VERSION="${RAW_TAG#v}"
else
VERSION="$(python -c "import json,urllib.request;print(json.load(urllib.request.urlopen('https://pypi.org/pypi/${{ env.PACKAGE_NAME }}/json'))['info']['version'])")"
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Fetch PyPI sdist URL and SHA256 (with short retry to avoid race)
id: sdist
shell: bash
env:
VERSION: ${{ steps.ver.outputs.version }}
run: |
PYPI_JSON="https://pypi.org/pypi/${PACKAGE_NAME}/${VERSION}/json"
OUT=$(python -c "import json,urllib.request,hashlib,os; d=json.load(urllib.request.urlopen('${PYPI_JSON}')); sd=[u for u in d['urls'] if u.get('packagetype')=='sdist']; u=sd[0]['url'] if sd else (_ for _ in ()).throw(SystemExit(1)); h=hashlib.sha256(urllib.request.urlopen(u).read()).hexdigest(); print(u); print(h)")
SDIST_URL="$(echo "$OUT" | sed -n '1p')"
SDIST_SHA256="$(echo "$OUT" | sed -n '2p')"
{
echo "sdist_url=$SDIST_URL"
echo "sha256=$SDIST_SHA256"
} >> "$GITHUB_OUTPUT"
- name: Set up conda (Miniforge)
uses: conda-incubator/setup-miniconda@v3
with:
miniforge-version: latest
use-mamba: true
auto-activate-base: true
channels: conda-forge
- name: Create env for conda-smithy
run: mamba create -n cf -y conda-smithy ruamel.yaml
- name: Authenticate gh CLI
run: gh auth status
- name: Clone your feedstock fork (track upstream/main)
run: |
test -n "$FEEDSTOCK_FORK"
gh repo clone "$FEEDSTOCK_FORK" feedstock
cd feedstock
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git remote remove upstream 2>/dev/null || true
git remote add upstream https://github.com/conda-forge/${{ env.PACKAGE_NAME }}-feedstock.git
git fetch upstream main
git checkout main
git reset --hard upstream/main
- name: Copy your meta.yaml into the feedstock
working-directory: feedstock
run: |
cp ../biapy/utils/env/conda_forge_meta.yaml recipe/meta.yaml
git add recipe/meta.yaml
git commit -m "Import project's conda_forge_meta.yaml as recipe/meta.yaml"
- name: Create bump branch and update version + sha256 (robust)
working-directory: feedstock
env:
VERSION: ${{ steps.ver.outputs.version }}
SDIST_SHA256: ${{ steps.sdist.outputs.sha256 }}
shell: bash
run: |
BRANCH="bump-v$VERSION-${GITHUB_RUN_ID}"
git checkout -B "$BRANCH"
python - <<'PY'
import os, re, pathlib
p = pathlib.Path("recipe") / "meta.yaml"
s = p.read_text(encoding="utf-8")
ver = os.environ["VERSION"]
sha = os.environ["SDIST_SHA256"]
s, n1 = re.subn(r'{%\s*set\s+version\s*=\s*"[^"]+"\s*%}',
'{% set version = "' + ver + '" %}', s)
if re.search(r'(?m)^\s*sha256\s*:\s*[0-9A-Fa-f]+', s):
s, n2 = re.subn(r'(?m)^(?P<indent>\s*sha256\s*:\s*)([0-9A-Fa-f]+)\s*$',
r'\g<indent>' + sha, s)
else:
m = re.search(r'(?ms)^(?P<indent>\s*)source:\s*\n(?P<body>(?:^\s+.*\n)+)', s)
if not m:
raise SystemExit("Could not locate 'source:' block in recipe/meta.yaml")
body = m.group('body')
mu = re.search(r'(?m)^(?P<uindent>\s*)url\s*:\s*\S+\s*$', body)
if not mu:
raise SystemExit("Could not locate 'url:' line in source block")
uindent = mu.group('uindent')
def _ins_sha(murl):
line = murl.group(0)
return line + "\n" + f"{uindent}sha256: {sha}"
body2, nurl = re.subn(r'(?m)^(%surl\s*:\s*\S+\s*)$' % re.escape(uindent), _ins_sha, body, count=1)
s = s[:m.start('body')] + body2 + s[m.end('body'):]
p.write_text(s, encoding="utf-8")
PY
git add recipe/meta.yaml
git commit -m "Bump to v$VERSION (update version and sha256)"
- name: Validate recipe YAML has sha256 under source
working-directory: feedstock
run: |
conda run -n cf python - <<'PY'
import sys
from ruamel.yaml import YAML
from pathlib import Path
yaml = YAML(typ="safe")
data = yaml.load(Path("recipe/meta.yaml").read_text())
src = data.get("source", {})
if isinstance(src, dict):
ok = "sha256" in src
elif isinstance(src, list) and src and isinstance(src[0], dict):
ok = "sha256" in src[0]
else:
ok = False
if not ok:
print("ERROR: recipe/meta.yaml 'source' lacks 'sha256:'", file=sys.stderr)
sys.exit(1)
print("OK: sha256 present in source")
PY
- name: (Optional) conda-smithy rerender
working-directory: feedstock
run: |
conda run -n cf conda-smithy rerender -c auto || true
if ! git diff --quiet; then
git add .
git commit -m "conda-smithy rerender"
fi
- name: Configure git auth for push
working-directory: feedstock
run: |
gh auth setup-git
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${FEEDSTOCK_FORK}.git"
- name: Push branch to your fork
working-directory: feedstock
env:
VERSION: ${{ steps.ver.outputs.version }}
run: |
BRANCH="bump-v$VERSION-${GITHUB_RUN_ID}"
git push --force --set-upstream origin "$BRANCH"
- name: Open PR to conda-forge feedstock
working-directory: feedstock
env:
VERSION: ${{ steps.ver.outputs.version }}
FORK: ${{ env.FEEDSTOCK_FORK }}
run: |
BRANCH="bump-v$VERSION-${GITHUB_RUN_ID}"
TITLE="biapy v$VERSION"
BODY="Automated bump to $VERSION after GitHub Release. Recipe copied from project: \`biapy/utils/env/conda_forge_meta.yaml\`. Version and sha256 updated from PyPI sdist."
OWNER="${FORK%%/*}"
gh pr create \
--repo conda-forge/biapy-feedstock \
--title "$TITLE" \
--body "$BODY" \
--head "${OWNER}:${BRANCH}" \
--base "main"
- name: Enable auto-merge on PR
working-directory: feedstock
env:
GH_TOKEN: ${{ secrets.CF_GH_TOKEN }}
run: |
# Get the last PR number created by this workflow run
PR_NUMBER=$(gh pr list \
--repo conda-forge/${PACKAGE_NAME}-feedstock \
--head "$(echo $FEEDSTOCK_FORK | cut -d/ -f1):bump-v${{ steps.ver.outputs.version }}-${GITHUB_RUN_ID}" \
--json number --jq '.[0].number')
echo "Enabling auto-merge for PR #$PR_NUMBER"
gh pr merge "$PR_NUMBER" \
--repo conda-forge/${PACKAGE_NAME}-feedstock \
--auto --merge