Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ updates:
- "dependencies"
reviewers:
- "matthewfeickert"
cooldown:
default-days: 7
Comment on lines +17 to +18

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@henryiii we had some discussion on the appropriate duration for cooldowns. Do you have thoughts here?


# Ignore all pip dependencies to avoid PRs to update tests/constraints.txt
- package-ecosystem: "pip"
Expand All @@ -22,3 +24,5 @@ updates:
interval: "weekly"
ignore:
- dependency-name: "*"
cooldown:
default-days: 7
90 changes: 55 additions & 35 deletions .github/workflows/bump-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ jobs:
permissions:
contents: write # for Git to git push
runs-on: ubuntu-latest
environment:
name: ci
deployment: false
if: github.repository == 'scikit-hep/pyhf'

steps:
Expand All @@ -51,6 +54,7 @@ jobs:
ref: ${{ github.event.inputs.target_branch }}
fetch-depth: 0
token: ${{ secrets.ACCESS_TOKEN }}
persist-credentials: false

- name: Check target branch is intended for release
if: github.event.inputs.force == 'false'
Expand All @@ -77,13 +81,13 @@ jobs:
echo "* Current version: ${current_tag}"
echo "* Latest stable version: ${latest_stable_tag}"

if [ ${{ github.event.inputs.release_candidate }} == 'true' ]; then
echo "* Attempting a ${{ github.event.inputs.part }} version release candidate bump from ${current_tag} to: ${{ github.event.inputs.new_version }}"
if [ ${GITHUB_EVENT_INPUTS_RELEASE_CANDIDATE} == 'true' ]; then
echo "* Attempting a ${GITHUB_EVENT_INPUTS_PART} version release candidate bump from ${current_tag} to: ${GITHUB_EVENT_INPUTS_NEW_VERSION}"
else
# For ease of use, set current tag to latest stable
current_tag="${latest_stable_tag}"

echo "* Attempting a ${{ github.event.inputs.part }} version bump from ${current_tag} to: ${{ github.event.inputs.new_version }}"
echo "* Attempting a ${GITHUB_EVENT_INPUTS_PART} version bump from ${current_tag} to: ${GITHUB_EVENT_INPUTS_NEW_VERSION}"
fi

echo "* Validating bump target version matches SemVer..."
Expand All @@ -102,7 +106,7 @@ jobs:

# IFS is single charecter, so split on the 'r' in "rc"
IFS='r' read bump_version bump_rc <<EOF
${{ github.event.inputs.new_version }}
${GITHUB_EVENT_INPUTS_NEW_VERSION}
EOF
bump_rc="${bump_rc:1}"

Expand All @@ -113,87 +117,91 @@ jobs:
unset bump_version

# Check release candidates are valid before proceeding
if [ ${{ github.event.inputs.release_candidate }} == 'true' ]; then
if [ ${GITHUB_EVENT_INPUTS_RELEASE_CANDIDATE} == 'true' ]; then
if [ -z "${current_rc}" ]; then
current_rc=0
fi
if [ "${bump_rc}" != "$((${current_rc} + 1))" ]; then
echo "ERROR: ${{ github.event.inputs.new_version }} is more than 1 release candidate version greater then ${current_tag}"
echo "ERROR: ${GITHUB_EVENT_INPUTS_NEW_VERSION} is more than 1 release candidate version greater then ${current_tag}"
exit 1
fi
else
if [ ! -z "${bump_rc}" ]; then
echo "ERROR: ${{ github.event.inputs.new_version }} contains a release candidate signature rc${bump_rc} but was marked as stable release."
echo "ERROR: ${GITHUB_EVENT_INPUTS_NEW_VERSION} contains a release candidate signature rc${bump_rc} but was marked as stable release."
exit 1
fi
fi

if [ ${{ github.event.inputs.part }} == "major" ]; then
if [ ${GITHUB_EVENT_INPUTS_PART} == "major" ]; then
# Minor version should be zero
if [ "${bump_minor}" != "0" ]; then
echo "ERROR: ${{ github.event.inputs.part }} release attempted, ${{ github.event.inputs.new_version }} minor version should equal 0."
echo "ERROR: ${GITHUB_EVENT_INPUTS_PART} release attempted, ${GITHUB_EVENT_INPUTS_NEW_VERSION} minor version should equal 0."
exit 1
fi
# Patch version should be zero
if [ "${bump_patch}" != "0" ]; then
echo "ERROR: ${{ github.event.inputs.part }} release attempted, ${{ github.event.inputs.new_version }} patch version should equal 0."
echo "ERROR: ${GITHUB_EVENT_INPUTS_PART} release attempted, ${GITHUB_EVENT_INPUTS_NEW_VERSION} patch version should equal 0."
exit 1
fi
if [ "${bump_major}" != "$((${current_major} + 1))" ]; then
if ! ([ "${bump_major}" == "${current_major}" ] && [ ${{ github.event.inputs.release_candidate }} == 'true' ]); then
echo "ERROR: ${{ github.event.inputs.part }} release candidate release attempted, but ${{ github.event.inputs.new_version }} is more than 1 ${{ github.event.inputs.part }} version greater then ${current_tag}."
if ! ([ "${bump_major}" == "${current_major}" ] && [ ${GITHUB_EVENT_INPUTS_RELEASE_CANDIDATE} == 'true' ]); then
echo "ERROR: ${GITHUB_EVENT_INPUTS_PART} release candidate release attempted, but ${GITHUB_EVENT_INPUTS_NEW_VERSION} is more than 1 ${GITHUB_EVENT_INPUTS_PART} version greater then ${current_tag}."
exit 1
fi
fi
fi

if [ ${{ github.event.inputs.part }} == "minor" ]; then
if [ ${GITHUB_EVENT_INPUTS_PART} == "minor" ]; then
# Major versions should be equal
if [ "${bump_major}" != "${current_major}" ]; then
echo "ERROR: ${{ github.event.inputs.part }} release attempted, but ${{ github.event.inputs.new_version }} major version not equal to ${current_tag}."
echo "ERROR: ${GITHUB_EVENT_INPUTS_PART} release attempted, but ${GITHUB_EVENT_INPUTS_NEW_VERSION} major version not equal to ${current_tag}."
exit 1
fi
# Patch version should be zero
if [ "${bump_patch}" != "0" ]; then
echo "ERROR: ${{ github.event.inputs.part }} release attempted, ${{ github.event.inputs.new_version }} patch version should equal 0."
echo "ERROR: ${GITHUB_EVENT_INPUTS_PART} release attempted, ${GITHUB_EVENT_INPUTS_NEW_VERSION} patch version should equal 0."
exit 1
fi
if [ "${bump_minor}" != "$((${current_minor} + 1))" ]; then
if ! ([ "${bump_minor}" == "${current_minor}" ] && [ ${{ github.event.inputs.release_candidate }} == 'true' ]); then
echo "ERROR: ${{ github.event.inputs.part }} release candidate release attempted, but ${{ github.event.inputs.new_version }} is more than 1 ${{ github.event.inputs.part }} version greater then ${current_tag}."
if ! ([ "${bump_minor}" == "${current_minor}" ] && [ ${GITHUB_EVENT_INPUTS_RELEASE_CANDIDATE} == 'true' ]); then
echo "ERROR: ${GITHUB_EVENT_INPUTS_PART} release candidate release attempted, but ${GITHUB_EVENT_INPUTS_NEW_VERSION} is more than 1 ${GITHUB_EVENT_INPUTS_PART} version greater then ${current_tag}."
exit 1
fi
fi
fi

if [ ${{ github.event.inputs.part }} == "patch" ]; then
if [ ${GITHUB_EVENT_INPUTS_PART} == "patch" ]; then
# Major versions should be equal
if [ "${bump_major}" != "${current_major}" ]; then
echo "ERROR: ${{ github.event.inputs.part }} release attempted, but ${{ github.event.inputs.new_version }} major version not equal to ${current_tag}."
echo "ERROR: ${GITHUB_EVENT_INPUTS_PART} release attempted, but ${GITHUB_EVENT_INPUTS_NEW_VERSION} major version not equal to ${current_tag}."
exit 1
fi
# Minor versions should be equal
if [ "${bump_minor}" != "${current_minor}" ]; then
echo "ERROR: ${{ github.event.inputs.part }} release attempted, but ${{ github.event.inputs.new_version }} minor version not equal to ${current_tag}."
echo "ERROR: ${GITHUB_EVENT_INPUTS_PART} release attempted, but ${GITHUB_EVENT_INPUTS_NEW_VERSION} minor version not equal to ${current_tag}."
exit 1
fi
if [ "${bump_patch}" != "$((${current_patch} + 1))" ]; then
if ! ([ "${bump_patch}" == "${current_patch}" ] && [ ${{ github.event.inputs.release_candidate }} == 'true' ]); then
echo "ERROR: ${{ github.event.inputs.part }} release candidate release attempted, but ${{ github.event.inputs.new_version }} is more than 1 ${{ github.event.inputs.part }} version greater then ${current_tag}."
if ! ([ "${bump_patch}" == "${current_patch}" ] && [ ${GITHUB_EVENT_INPUTS_RELEASE_CANDIDATE} == 'true' ]); then
echo "ERROR: ${GITHUB_EVENT_INPUTS_PART} release candidate release attempted, but ${GITHUB_EVENT_INPUTS_NEW_VERSION} is more than 1 ${GITHUB_EVENT_INPUTS_PART} version greater then ${current_tag}."
exit 1
fi
fi
fi

echo " ...version bump validated!"
if [ ${{ github.event.inputs.release_candidate }} == 'true' ]; then
echo "* Bumping version ${current_tag} to ${{ github.event.inputs.part }} version release candidate ${{ github.event.inputs.new_version }}"
if [ ${GITHUB_EVENT_INPUTS_RELEASE_CANDIDATE} == 'true' ]; then
echo "* Bumping version ${current_tag} to ${GITHUB_EVENT_INPUTS_PART} version release candidate ${GITHUB_EVENT_INPUTS_NEW_VERSION}"
else
echo "* Bumping version ${current_tag} to ${{ github.event.inputs.part }} version ${{ github.event.inputs.new_version }}"
echo "* Bumping version ${current_tag} to ${GITHUB_EVENT_INPUTS_PART} version ${GITHUB_EVENT_INPUTS_NEW_VERSION}"
fi

echo "steps.script.outputs.old_tag=v${current_tag}"
echo "old_tag=v${current_tag}" >> $GITHUB_OUTPUT
env:
GITHUB_EVENT_INPUTS_RELEASE_CANDIDATE: ${{ github.event.inputs.release_candidate }}
GITHUB_EVENT_INPUTS_PART: ${{ github.event.inputs.part }}
GITHUB_EVENT_INPUTS_NEW_VERSION: ${{ github.event.inputs.new_version }}

- name: Set up Python
if: success()
Expand Down Expand Up @@ -222,16 +230,18 @@ jobs:
)
shell: bash
run: |
tbump --non-interactive --no-push ${{ github.event.inputs.new_version }}
tbump --non-interactive --no-push ${GITHUB_EVENT_INPUTS_NEW_VERSION}
env:
GITHUB_EVENT_INPUTS_NEW_VERSION: ${{ github.event.inputs.new_version }}

- name: Update the Git tag annotation
if: ${{ github.event.inputs.dry_run }} == 'false'
if: ${{ github.event.inputs.dry_run == 'false' }}
shell: bash
run: |
OLD_TAG=${{ steps.script.outputs.old_tag }}
OLD_TAG=${STEPS_SCRIPT_OUTPUTS_OLD_TAG}
git tag -n99 --list "${OLD_TAG}"

NEW_TAG=v${{ github.event.inputs.new_version }}
NEW_TAG=v${GITHUB_EVENT_INPUTS_NEW_VERSION}
Comment on lines +241 to +244

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
file=".github/workflows/bump-version.yml"
wc -l "$file"
sed -n '40,90p' "$file"
sed -n '230,295p' "$file"
printf '\nAll relevant identifiers and commands:\n'
rg -n -C 3 'old_tag|OLD_TAG|git log|git tag|git push|persist-credentials|force|script:' "$file"

Repository: scikit-hep/pyhf

Length of output: 8436


🏁 Script executed:

#!/bin/bash
set -eu
file=".github/workflows/bump-version.yml"
sed -n '85,210p' "$file"
printf '\nRevision resolution for an empty OLD_TAG:\n'
git rev-parse --revs-only '..HEAD' || true
git rev-parse --symbolic --revs-only '..HEAD' || true
git log --pretty=format:'%s' '..HEAD' --regexp-ignore-case --extended-regexp --grep='^([a-z]*?):' | head -20
printf '\nRepository state:\n'
git status --short
git rev-parse --is-inside-work-tree

Repository: scikit-hep/pyhf

Length of output: 6569


Populate OLD_TAG when force is true.

When force is true, the script step is skipped, so steps.script.outputs.old_tag is empty. The range at line 247 then becomes ..HEAD, equivalent to HEAD..HEAD, and the release annotation contains no changes. Compute OLD_TAG in an unconditional step, or stop before creating the annotation when it is empty.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/bump-version.yml around lines 241 - 244, Ensure OLD_TAG is
populated even when the force input skips the script step by computing it in an
unconditional step before the git tag and annotation logic. Alternatively,
detect an empty OLD_TAG and stop before creating the release annotation;
preserve the existing behavior for non-force runs.

Source: MCP tools

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@kratsg note that .github/workflows/bump-version.yml is going to be removed in PR #2743 and so we don't have to be too concerned about that here.

git tag -n99 --list "${NEW_TAG}"

CHANGES=$(git log --pretty=format:'%s' "${OLD_TAG}"..HEAD --regexp-ignore-case --extended-regexp --grep='^([a-z]*?):')
Expand All @@ -245,24 +255,34 @@ jobs:
SANITIZED_CHANGES=$(echo "${CHANGES}" | sed -e 's/^/<li>/' -e 's|$|</li>|' -e 's/(#[0-9]\+)//' -e 's/"/'"'"'/g')
NUM_CHANGES=$(echo -n "${CHANGES}" | grep -c '^')

if [ ${{ github.event.inputs.release_candidate }} == 'true' ]; then
git tag "${NEW_TAG}" "${NEW_TAG}"^{} -f -m "$(printf "This is a ${{ github.event.inputs.part }} release candidate from ${OLD_TAG} → ${NEW_TAG}.\n\nChanges:\n${CHANGES_NEWLINE}")"
if [ ${GITHUB_EVENT_INPUTS_RELEASE_CANDIDATE} == 'true' ]; then
git tag "${NEW_TAG}" "${NEW_TAG}"^{} -f -m "$(printf "This is a ${GITHUB_EVENT_INPUTS_PART} release candidate from ${OLD_TAG} → ${NEW_TAG}.\n\nChanges:\n${CHANGES_NEWLINE}")"
else
git tag "${NEW_TAG}" "${NEW_TAG}"^{} -f -m "$(printf "This is a ${{ github.event.inputs.part }} release from ${OLD_TAG} → ${NEW_TAG}.\n\nChanges:\n${CHANGES_NEWLINE}")"
git tag "${NEW_TAG}" "${NEW_TAG}"^{} -f -m "$(printf "This is a ${GITHUB_EVENT_INPUTS_PART} release from ${OLD_TAG} → ${NEW_TAG}.\n\nChanges:\n${CHANGES_NEWLINE}")"
fi

git tag -n99 --list "${NEW_TAG}"
env:
STEPS_SCRIPT_OUTPUTS_OLD_TAG: ${{ steps.script.outputs.old_tag }}
GITHUB_EVENT_INPUTS_NEW_VERSION: ${{ github.event.inputs.new_version }}
GITHUB_EVENT_INPUTS_RELEASE_CANDIDATE: ${{ github.event.inputs.release_candidate }}
GITHUB_EVENT_INPUTS_PART: ${{ github.event.inputs.part }}

- name: Show annotated Git tag
shell: bash
run: |
git show v${{ github.event.inputs.new_version }}
git show v${GITHUB_EVENT_INPUTS_NEW_VERSION}
env:
GITHUB_EVENT_INPUTS_NEW_VERSION: ${{ github.event.inputs.new_version }}

- name: Push new tag back to GitHub
shell: bash
run: |
if [ ${{ github.event.inputs.dry_run }} == 'true' ]; then
if [ ${GITHUB_EVENT_INPUTS_DRY_RUN} == 'true' ]; then
echo "# DRY RUN"
else
git push origin ${{ github.event.inputs.target_branch }} --tags
git push origin ${GITHUB_EVENT_INPUTS_TARGET_BRANCH} --tags
fi
env:
GITHUB_EVENT_INPUTS_DRY_RUN: ${{ github.event.inputs.dry_run }}
GITHUB_EVENT_INPUTS_TARGET_BRANCH: ${{ github.event.inputs.target_branch }}
2 changes: 2 additions & 0 deletions .github/workflows/ci-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ jobs:

steps:
- uses: actions/checkout@v7
with:
persist-credentials: false

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
test:

runs-on: ${{ matrix.os }}
environment:
name: ci
deployment: false
# On push events run the CI only on main by default, but run on any branch if the commit message contains '[ci all]'
if: >-
github.event_name != 'push'
Expand All @@ -40,6 +43,8 @@ jobs:

steps:
- uses: actions/checkout@v7
with:
persist-credentials: false

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
persist-credentials: false

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/dependencies-head.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ permissions:
jobs:
release-candidates:

name: PyPI release candidates
if: github.repository == 'scikit-hep/pyhf'
runs-on: ${{ matrix.os }}
strategy:
Expand All @@ -25,6 +26,8 @@ jobs:

steps:
- uses: actions/checkout@v7
with:
persist-credentials: false

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
Expand All @@ -47,6 +50,7 @@ jobs:

scipy:

name: SciPy nightly wheel
if: github.repository == 'scikit-hep/pyhf'
runs-on: ${{ matrix.os }}
strategy:
Expand All @@ -56,6 +60,8 @@ jobs:

steps:
- uses: actions/checkout@v7
with:
persist-credentials: false

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
Expand All @@ -77,6 +83,7 @@ jobs:

iminuit:

name: iminuit nightly source
if: github.repository == 'scikit-hep/pyhf'
runs-on: ${{ matrix.os }}
strategy:
Expand All @@ -86,6 +93,8 @@ jobs:

steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
with:
Expand All @@ -104,6 +113,7 @@ jobs:

uproot5:

name: uproot nightly wheel
if: github.repository == 'scikit-hep/pyhf'
runs-on: ${{ matrix.os }}
strategy:
Expand All @@ -113,6 +123,8 @@ jobs:

steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
with:
Expand All @@ -130,6 +142,7 @@ jobs:

matplotlib:

name: Matplotlib nightly wheel
if: github.repository == 'scikit-hep/pyhf'
runs-on: ${{ matrix.os }}
strategy:
Expand All @@ -139,6 +152,8 @@ jobs:

steps:
- uses: actions/checkout@v7
with:
persist-credentials: false

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
Expand Down Expand Up @@ -169,6 +184,7 @@ jobs:

pytest:

name: pytest nightly source
if: github.repository == 'scikit-hep/pyhf'
runs-on: ${{ matrix.os }}
strategy:
Expand All @@ -178,6 +194,8 @@ jobs:

steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
with:
Expand Down
Loading
Loading