A Python library for utility functions and class helpful for custom GitHub actions.
Project description
github-action-toolkit - Python Package
A Python library for building powerful GitHub Actions with type safety, rich output formatting, and comprehensive developer tools.
Key Features
- ✨ Type-safe with full type annotations and modern Python 3.11+ practices
- 🛡️ Exception taxonomy with specific exception types for better error handling
- 🔧 Actionable error messages that explain what went wrong and how to fix it
- 🎯 Scoped environment helpers for temporary environment variables
- 🚦 Graceful cancellation support with SIGTERM/SIGINT handlers
- 📚 Comprehensive documentation with examples and best practices
- 🔒 Security-focused with input validation and secrets masking
- 🎨 Rich job summaries with tables, code blocks, and templates
Quick Start
from github_action_toolkit import (
get_user_input,
get_user_input_as,
set_output,
info,
notice,
JobSummary,
)
# Type-safe input handling
name = get_user_input('name') or 'World'
timeout = get_user_input_as('timeout', int, default_value=30)
# Rich console output
info(f'Processing for {name}...')
notice(f'Hello, {name}!', title='Greeting')
# Set outputs for other steps
set_output('greeting', f'Hello, {name}!')
# Create formatted job summary
summary = JobSummary()
summary.add_heading('Execution Summary', 1)
summary.add_table([
['Parameter', 'Value'],
['Name', name],
['Timeout', f'{timeout}s'],
])
summary.add_quote('✓ Action completed successfully!')
summary.write()
Installation
Install via pip:
pip install github-action-toolkit
Or with uv:
uv add github-action-toolkit
Core Capabilities
Input & Output Management
from github_action_toolkit import (
get_user_input,
get_user_input_as,
set_output,
set_env,
with_env,
)
# Get inputs with type conversion
debug = get_user_input_as('debug', bool, default_value=False)
retries = get_user_input_as('retries', int, default_value=3)
# Set outputs for subsequent steps
set_output('result', 'success')
# Manage environment variables
set_env('DEPLOY_URL', 'https://app.example.com')
# Temporary environment variables with automatic cleanup
with with_env(DEBUG='true', LOG_LEVEL='verbose'):
# Variables are set here
run_process()
# Variables automatically restored here
Logging & Annotations
from github_action_toolkit import info, warning, error, notice, group
# Structured console output
info('Starting process...')
warning('Resource usage high', title='Performance Warning')
notice('Deployment successful', title='Success')
# File annotations with line/column
error(
'Undefined variable "x"',
file='src/main.py',
line=42,
col=10,
title='Syntax Error'
)
# Organized output with collapsible groups
with group('Build Process'):
info('Compiling source...')
info('Running tests...')
info('Build complete!')
Rich Job Summaries
from github_action_toolkit import JobSummary, JobSummaryTemplate
# Use pre-built templates
summary = JobSummaryTemplate.test_report(
title='Test Results',
passed=45,
failed=2,
skipped=1,
duration='12.5s'
)
# Or build custom summaries
summary = JobSummary()
summary.add_heading('Deployment Status', 1)
summary.add_table([
['Environment', 'Status', 'URL'],
['Staging', '✓ Active', 'https://staging.example.com'],
['Production', '✓ Active', 'https://app.example.com'],
])
summary.add_separator()
summary.add_code_block('version: 2.5.0\nreleased: 2024-01-15', 'yaml')
summary.write()
GitHub API Integration
from github_action_toolkit import GitHubAPIClient
client = GitHubAPIClient()
# Get repository information
repo = client.get_repository('owner/repo')
print(f'Stars: {repo.stargazers_count}')
# List and paginate
issues = client.paginate(lambda: repo.get_issues(state='open'))
for issue in issues:
print(f'#{issue.number}: {issue.title}')
Artifacts & Caching
from github_action_toolkit import GitHubArtifacts, GitHubCache
# Upload artifacts
artifacts = GitHubArtifacts()
artifacts.upload_artifact(
name='test-results',
paths=['reports/', 'coverage.xml'],
retention_days=30
)
# Use caching for dependencies
cache = GitHubCache()
cache_hit = cache.restore_cache(
paths=['.venv'],
key='python-deps-v1'
)
if not cache_hit:
# Install dependencies
install_dependencies()
cache.save_cache(paths=['.venv'], key='python-deps-v1')
Graceful Cancellation
from github_action_toolkit import CancellationHandler
from github_action_toolkit.exceptions import CancellationRequested
cancellation = CancellationHandler()
def cleanup():
print('Cleaning up resources...')
# Cleanup logic here
cancellation.register(cleanup)
cancellation.enable()
try:
# Long-running operation
process_data()
except CancellationRequested:
print('Operation cancelled gracefully')
raise SystemExit(0)
Documentation
Full documentation is available at: https://github-action-toolkit.readthedocs.io/
Quick Links
- Quickstart Guide - Get started in minutes
- Examples - Complete workflow examples
- API Reference - Detailed function documentation
Comparison with Javascript @actions/toolkit
| Feature | Python | Javascript |
|---|---|---|
| Syntax | Clean, readable Python | JavaScript/TypeScript |
| Type Safety | Full type hints | TypeScript types |
| Dependencies | Simple pip/uv install | npm with bundling |
| Data Processing | Rich ecosystem (pandas, numpy) | Limited native support |
| Learning Curve | Python (widely known) | JavaScript + Actions API |
| Local Testing | Built-in simulator | Manual setup needed |
Quick Comparison Example
Before (JavaScript):
const core = require('@actions/core');
const name = core.getInput('name', { required: true });
core.setOutput('greeting', `Hello ${name}`);
core.info('Process complete');
After (Python):
from github_action_toolkit import get_user_input, set_output, info
name = get_user_input('name')
if not name:
raise ValueError("name is required")
set_output('greeting', f'Hello {name}')
info('Process complete')
Example Action
Here's a complete example of a Python action:
action.py:
from github_action_toolkit import (
get_user_input,
get_user_input_as,
set_output,
info,
error,
JobSummary,
)
def main():
try:
# Get inputs
name = get_user_input('name') or 'World'
enthusiastic = get_user_input_as('enthusiastic', bool, default_value=False)
# Create greeting
greeting = f"Hello, {name}{'!' if enthusiastic else '.'}"
info(greeting)
# Set output
set_output('greeting', greeting)
# Create summary
summary = JobSummary()
summary.add_heading('Greeting Action', 1)
summary.add_quote(greeting)
summary.write()
return 0
except Exception as e:
error(f'Action failed: {e}', title='Error')
return 1
if __name__ == '__main__':
raise SystemExit(main())
action.yml:
name: 'Python Greeter'
description: 'A simple greeting action'
inputs:
name:
description: 'Name to greet'
required: false
default: 'World'
enthusiastic:
description: 'Add enthusiasm'
required: false
default: 'false'
outputs:
greeting:
description: 'The greeting message'
runs:
using: 'composite'
steps:
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install github-action-toolkit
shell: bash
- run: python ${{ github.action_path }}/action.py
shell: bash
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
License
Apache License 2.0 - see LICENSE for details.
Project Documentation
For development workflows, see development.md.
For release process, see release.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file github_action_toolkit-0.9.0.tar.gz.
File metadata
- Download URL: github_action_toolkit-0.9.0.tar.gz
- Upload date:
- Size: 239.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a500223f91bdaf32318a68bf40e98a8244035d4471f6ac8cd27d515e49b2a3b8
|
|
| MD5 |
b59b04fb36a61383e3603ae1605271af
|
|
| BLAKE2b-256 |
8b5bfbb0bc28285a112d58ca964d19ddf394f706d6f27a052bac8f4fa2ad1be3
|
File details
Details for the file github_action_toolkit-0.9.0-py3-none-any.whl.
File metadata
- Download URL: github_action_toolkit-0.9.0-py3-none-any.whl
- Upload date:
- Size: 51.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56588a16662f27bfcb8d780171fdf0c39848b0c0017932663c97d497911b8ce0
|
|
| MD5 |
643f511db8578859705f063f1f055309
|
|
| BLAKE2b-256 |
428807cf968812afbbf5fd2718be9247388b0dcc37f49587da817cafbef97941
|