Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .github/workflows/release-new.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
id: app_token
uses: actions/create-github-app-token@v2
with:
app-id: 2959093
app-id: ${{ vars.RELEASE_BOT_APP_ID }}
private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}

Expand Down
119 changes: 119 additions & 0 deletions .github/workflows/release-undo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
name: Undo Release

on:
workflow_dispatch:
inputs:
version:
description: "Released version to undo (example: 0.14.0)"
required: true
type: string
confirm:
description: 'Type "UNDO RELEASE" to continue'
required: true
type: string
delete_github_release:
description: "Delete the GitHub release for tag v<version>"
required: true
type: boolean
default: true
delete_git_tag:
description: "Delete tag v<version> from origin"
required: true
type: boolean
default: true
yank_pypi:
description: "Yank redisvl==<version> on PyPI"
required: true
type: boolean
default: true

permissions:
contents: write

env:
PACKAGE_NAME: redisvl

jobs:
undo-release:
runs-on: ubuntu-latest

steps:
- name: Validate inputs
env:
VERSION: ${{ inputs.version }}
CONFIRM: ${{ inputs.confirm }}
run: |
set -euo pipefail
if [ "${CONFIRM}" != "UNDO RELEASE" ]; then
echo "Confirmation text mismatch."
exit 1
fi
if ! [[ "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+([a-zA-Z0-9\.\-]+)?$ ]]; then
echo "Version must look like 1.2.3 (optionally with a suffix)."
exit 1
fi
echo "TAG=v${VERSION}" >> "$GITHUB_ENV"
echo "SPEC=${PACKAGE_NAME}==${VERSION}" >> "$GITHUB_ENV"

- name: Generate GitHub App token
id: app_token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ vars.RELEASE_BOT_APP_ID }}
private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}

- name: Checkout repository
if: ${{ inputs.delete_git_tag }}
Copy link

Choose a reason for hiding this comment

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

Release deletion silently fails without repo checkout context

Medium Severity

The checkout step is conditional on inputs.delete_git_tag, but the gh release view/gh release delete commands also depend on having a repo context. When delete_github_release is true but delete_git_tag is false, no checkout occurs, and gh cannot determine the base repository. Because the gh release view error is suppressed by >/dev/null 2>&1, the step silently falls through to the else branch printing "No GitHub release found," even though the release exists. The checkout condition needs to also account for delete_github_release, or the gh commands need an explicit --repo flag.

Additional Locations (1)

Fix in Cursor Fix in Web

uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
token: ${{ steps.app_token.outputs.token }}

- name: Delete GitHub release
if: ${{ inputs.delete_github_release }}
env:
GH_TOKEN: ${{ steps.app_token.outputs.token }}
run: |
set -euo pipefail
if gh release view "${TAG}" >/dev/null 2>&1; then
gh release delete "${TAG}" --yes
echo "Deleted GitHub release ${TAG}."
else
echo "No GitHub release found for ${TAG}; skipping."
fi

- name: Delete git tag from origin
if: ${{ inputs.delete_git_tag }}
env:
GH_TOKEN: ${{ steps.app_token.outputs.token }}
run: |
set -euo pipefail
git fetch --tags --force
if git rev-parse "${TAG}" >/dev/null 2>&1; then
git tag -d "${TAG}" || true
fi
if git ls-remote --exit-code --tags origin "refs/tags/${TAG}" >/dev/null 2>&1; then
git push origin ":refs/tags/${TAG}"
echo "Deleted remote tag ${TAG}."
else
echo "Remote tag ${TAG} not found; skipping."
fi

- name: Install Python
if: ${{ inputs.yank_pypi }}
uses: actions/setup-python@v6
with:
python-version: "3.11"

- name: Yank package on PyPI
if: ${{ inputs.yank_pypi }}
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI }}
run: |
set -euo pipefail
python -m pip install --upgrade pip twine
twine yank "${SPEC}"
Copy link

Choose a reason for hiding this comment

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

twine yank is not a valid twine subcommand

High Severity

twine yank is not a valid subcommand. The twine CLI (latest version 6.1.0) only supports upload, check, and register subcommands. Running twine yank "${SPEC}" will fail with an unrecognized command error. PyPI yanking is currently only available through the PyPI web interface or by calling the PyPI API directly (e.g., via curl).

Fix in Cursor Fix in Web

echo "Yanked ${SPEC} on PyPI."
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.