Skip to main content

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

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

github_action_toolkit-0.9.0.tar.gz (239.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

github_action_toolkit-0.9.0-py3-none-any.whl (51.3 kB view details)

Uploaded Python 3

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

Hashes for github_action_toolkit-0.9.0.tar.gz
Algorithm Hash digest
SHA256 a500223f91bdaf32318a68bf40e98a8244035d4471f6ac8cd27d515e49b2a3b8
MD5 b59b04fb36a61383e3603ae1605271af
BLAKE2b-256 8b5bfbb0bc28285a112d58ca964d19ddf394f706d6f27a052bac8f4fa2ad1be3

See more details on using hashes here.

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

Hashes for github_action_toolkit-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 56588a16662f27bfcb8d780171fdf0c39848b0c0017932663c97d497911b8ce0
MD5 643f511db8578859705f063f1f055309
BLAKE2b-256 428807cf968812afbbf5fd2718be9247388b0dcc37f49587da817cafbef97941

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page