Automated summary
Automates a secure GitHub Actions workflow to publish Python packages to PyPI using OIDC (Trusted Publishers), with interactive PEP 440 versioning and project validation.
Strengths
- Validates project structure before attempting to publish
- Offers interactive PEP 440‑compliant version bumping (alpha, beta, RC, stable)
- Uses OIDC-based Trusted Publishers for enhanced security
- Automatically generates the required GitHub Actions workflow file
Limitations
- Requires a Git repository and targets only GitHub Actions for CI/CD
- Only supports Python packages using pyproject.toml, setup.py, or setup.cfg
- Interactive versioning may be too rigid for custom version schemes
When you need a secure, automated PyPI publishing pipeline with version bumping and project structure checks.
If you use a different CI system (e.g., Jenkins, GitLab CI) or prefer fully manual version control without an interactive assistant.
Security analysis
SafeThe skill performs standard package publishing tasks using secure OIDC method. It uses git commands and Python invocations for validation and configuration, but no destructive or exfiltrating actions are instructed. The generated workflow pushes packages to PyPI via trusted publisher, which is safe.
No concerns found
How this analysis is madeExamples
I want to publish my Python package to PyPI securely with automatic version bumping. Please use GitHub Actions and OIDC.Help me create a GitHub Actions workflow that publishes to PyPI using Trusted Publishers, with interactive version selection (alpha, beta, RC, stable).I need to publish a new release of my Python package. Guide me through version bumping and set up the PyPI publish workflow.name: secure-pypi-publish description: Complete workflow for publishing Python packages to PyPI securely using GitHub Actions and Trusted Publishers (OIDC). Includes interactive PEP 440 versioning, structure validation, and automatic workflow generation. allowed-tools: Bash(git:), Bash(python:), Read, Write, Edit, Question
Secure PyPI Publishing Workflow
You are a Python package publishing specialist. When the user activates this skill, execute the following sequential and interactive workflow:
Phase 1: Project Validation
1.1 Verify Git Environment
- Execute
git rev-parse --is-inside-work-treeto confirm you're in a Git repository - If not a Git repo, inform the user and halt the process
1.2 Detect Project Type
Search in order of preference:
pyproject.toml(recommended)setup.pysetup.cfg
Read the first file found and extract:
- Package name: Search in
[project.name],setup(name=...), or[metadata] name - Current version: Search in
[project.version],[tool.poetry.version],setup(version=...), or[metadata] version
1.3 Get Repository Information
- Execute
git remote get-url originto get the repo URL - Parse the URL to extract: owner/organization and repository name
- Validate that remote is configured correctly
1.4 Validate Minimum Structure
Verify that at least one exists:
- Source code directory (package name)
__init__.pyfile or Python modules
If validation fails, ask the user if they want to continue anyway.
Phase 2: Interactive Versioning (PEP 440)
2.1 Display Current Version
Present to the user:
Current version detected: X.Y.Z
Package name: your-package
Repository: owner/repo
2.2 Select Release Type
Use the question tool to ask:
Main question:
What kind of release is this?
Options:
Stable (e.g., 1.0.0)- Final release, production-readyAlpha (e.g., 1.0.0a1)- New features in development, unstable APIBeta (e.g., 1.0.0b1)- Feature complete, testing for bugsRelease Candidate (e.g., 1.0.0rc1)- Potential final version, final testing
2.3 For Pre-releases (Options 2-4)
If the user selects Alpha, Beta, or RC:
Ask for iteration number:
Enter the pre-release iteration number (default: 1):
- Validate it's a positive integer
- If empty, use 1
2.4 Calculate New Version
Apply PEP 440 rules:
For Stable:
- If current version is
1.2.3and user wants minor bump →1.3.0 - Ask which part to increment: major, minor, or patch
For Pre-releases:
- If current version is
1.2.3and user chooses Beta iteration 1 →1.2.3b1 - If pre-release already exists (e.g.,
1.2.3b1) and chooses Beta iteration 2 →1.2.3b2
PEP 440 Format:
- Alpha:
X.Y.ZaN(e.g.,1.0.0a1,2.3.4a2) - Beta:
X.Y.ZbN(e.g.,1.0.0b1,2.3.4b2) - Release Candidate:
X.Y.ZrcN(e.g.,1.0.0rc1,2.3.4rc3)
2.5 Confirm Version
Display:
New version will be: X.Y.Z[suffix]
Version breakdown:
- Base version: X.Y.Z
- Release type: [Stable|Alpha|Beta|Release Candidate]
- Pre-release iteration: N (if applicable)
Confirm this version? [y/N]
If not confirmed, return to step 2.2.
2.6 Update Configuration File
Modify the file detected in Phase 1:
pyproject.toml:
[project]
name = "your-package"
version = "X.Y.Zsuffix"
or if using Poetry:
[tool.poetry]
name = "your-package"
version = "X.Y.Zsuffix"
setup.py:
setup(
name="your-package",
version="X.Y.Zsuffix",
...
)
setup.cfg:
[metadata]
name = your-package
version = X.Y.Zsuffix
Use the Edit tool to make the precise change.
Phase 3: GitHub Actions Setup
3.1 Create Directory Structure
mkdir -p .github/workflows
3.2 Generate Workflow File
Create .github/workflows/pypi-publish.yml using the template from templates/pypi-publish.yml:
- Replace
{{PACKAGE_NAME}}with the package name - Workflow must use Trusted Publishers (OIDC) - DO NOT use API tokens
- Configure GitHub Environment:
pypi - Trigger: push tags with pattern
v*
3.3 Create/Update .gitignore (if necessary)
Verify if .gitignore exists and ensure it includes:
# Python
__pycache__/
*.py[cod]
*$py.class
dist/
build/
*.egg-info/
# Virtual environments
venv/
env/
.venv/
Phase 4: Final Instructions
Generate and display the following formatted output:
====================================================================
🎉 Your secure publishing flow (secure-pypi-publish) is ready!
====================================================================
To finish publishing version [X.Y.Zsuffix] of [package-name],
follow exactly these steps:
1️⃣ CONFIGURE TRUSTED PUBLISHER ON PYPI:
Go to: https://pypi.org/manage/account/publishing/
Click "Add a new pending publisher" and fill in:
- PyPI Project Name: [package-name]
- Owner: [owner]
- Repository name: [repo-name]
- Workflow name: pypi-publish.yml
- Environment name: pypi
Note: If the package already exists on PyPI, go to:
https://pypi.org/manage/project/[package-name]/publishing/
2️⃣ CREATE THE GITHUB ENVIRONMENT:
Go to: https://github.com/[owner]/[repo-name]/settings/environments/new
Create an environment named: pypi
(Optional) Add protection rules:
- Required reviewers for deployments
- Wait timer before deployments
- Deployment branches: main (or your default branch)
3️⃣ SAVE CHANGES IN GIT:
Run in your terminal:
git add .github/workflows/pypi-publish.yml [config-file]
git commit -m "chore: setup secure PyPI publishing for vX.Y.Zsuffix"
git push origin [default-branch]
4️⃣ CREATE THE TAG AND TRIGGER THE PIPELINE:
To trigger the publishing process, create a version tag and push it:
git tag -a vX.Y.Zsuffix -m "Release vX.Y.Zsuffix"
git push origin vX.Y.Zsuffix
👀 Track your publishing status at:
https://github.com/[owner]/[repo-name]/actions
📚 Documentation:
- PEP 440 Versioning: https://peps.python.org/pep-0440/
- Trusted Publishers: https://docs.pypi.org/trusted-publishers/
- GitHub Actions Environments: https://docs.github.com/en/actions/deployment/targeting-different-environments
💡 Tips:
- Test on TestPyPI first: Replace pypi.org with test.pypi.org in step 1
- Monitor the Actions run to catch any build errors
- Verify the package appears on PyPI after successful publish
====================================================================
Technical Notes
Parsing pyproject.toml
- Use simple regular expressions or manual parsing (avoid dependencies)
- Search for
[project]or[tool.poetry]section - Keep the rest of the file intact
Error Handling
- If configuration file cannot be parsed, show error and halt
- If current version doesn't comply with PEP 440, warn the user
- If remote is not configured, suggest
git remote add origin <url>
Optional Validations
- Check if package name already exists on PyPI (warning, not error)
- Check if there are uncommitted changes (ask if they want to continue)
Compatibility
- Support Python 3.8+
- Don't require external tools (only git and standard python)
- Work on Linux, macOS, and Windows
References
From the file to a first result
The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.
View the source and supporting filesThis download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.
1. Download the file
Download SKILL.mdFrom the root of a test project, save the file as .skill-downloads/secure-pypi-publishing-workflow-mrzxup71/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.
Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.
mkdir -p '.skill-downloads/secure-pypi-publishing-workflow-mrzxup71' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/secure-pypi-publishing-workflow-mrzxup71/download' --output '.skill-downloads/secure-pypi-publishing-workflow-mrzxup71/SKILL.md.part' && mv '.skill-downloads/secure-pypi-publishing-workflow-mrzxup71/SKILL.md.part' '.skill-downloads/secure-pypi-publishing-workflow-mrzxup71/SKILL.md'2. Check prerequisites
Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.
Tools declared by the author (check availability in your agent): Bash(git:*), Bash(python:*), Read, Write, Edit, Question
No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.
The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.
3. Load the skill
After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.
Claude Code
test -f '.skill-downloads/secure-pypi-publishing-workflow-mrzxup71/SKILL.md' && test -s '.skill-downloads/secure-pypi-publishing-workflow-mrzxup71/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/secure-pypi-publish' && cp -R '.skill-downloads/secure-pypi-publishing-workflow-mrzxup71' '.claude/skills/secure-pypi-publish'OpenSkills
OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.
Official OpenSkills installationopenskills install './.skill-downloads/secure-pypi-publishing-workflow-mrzxup71'openskills read 'secure-pypi-publishing-workflow-mrzxup71'Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.
For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.
openskills syncManual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.
4. Try a first task
Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:
Read .skill-downloads/secure-pypi-publishing-workflow-mrzxup71/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.
Configure a Chat Channel with SecretRefs
DevOps
Set up chat channels using non-interactive commands, with secrets only as SecretRefs. Covers gather, mutate, repair, and prove steps for reliable delivery.
Investigate ClickHouse CI Failures
DevOps
Investigate a ClickHouse CI failure end-to-end from a PR or S3 report URL. Fetches failed tests, classifies flaky vs real regression, and checks for existing issues/fixes.
Ansible PR Review
DevOps
Reviews an Ansible PR following the project's standardized process, including changelog checks, test coverage validation, and feedback tracking.