GitHub Artifacts¶
Upload and download workflow artifacts for sharing data between jobs.
Overview¶
The GitHubArtifacts class provides robust artifact management with upload/download capabilities, pattern matching, integrity checks, and error handling.
API Reference¶
GitHubArtifacts(github_token=None, github_repo=None)¶
Initializes the artifact manager for GitHub Actions artifact operations.
Both parameters are optional but environment variables for it needs to be present GITHUB_TOKEN and GITHUB_REPOSITORY respectively.
example:
>> from github_action_toolkit import GitHubArtifacts
>> artifacts = GitHubArtifacts()
GitHubArtifacts.get_artifacts(current_run_only=False, name_pattern=None)¶
Returns a list of GitHub Actions artifacts for the current repository with optional filtering.
current_run_only(optional): If True, only returns artifacts from the current workflow run (GITHUB_RUN_ID must be set in env).name_pattern(optional): Filter by name pattern using wildcards (e.g., “test-” or “-results”)
example:
>> artifacts = artifacts.get_artifacts(current_run_only=True)
>> for artifact in artifacts:
>> print(artifact.name)
# Output:
# running-tests
# publish-release
>> # Filter by pattern
>> test_artifacts = artifacts.get_artifacts(name_pattern="test-*")
>> for artifact in test_artifacts:
>> print(artifact.name)
# Output:
# test-results
# test-coverage
GitHubArtifacts.get_artifact(artifact_id)¶
Fetches a specific artifact by its ID.
example:
>> artifact = artifacts.get_artifact(artifact_id=123456)
>> print(artifact.name)
# Output
# running-tests
GitHubArtifacts.upload_artifact(name, paths=None, patterns=None, root_dir=None, retention_days=None, verify_checksum=True, max_retries=3)¶
Upload files as an artifact with pattern matching, compression, and integrity checks.
name: Artifact namepaths(optional): List of file/directory paths to includepatterns(optional): List of glob patterns (e.g., [”.log”, “build/**/.js”])root_dir(optional): Root directory for relative paths (defaults to current dir)retention_days(optional): Days to retain artifact (GitHub default applies if not set)verify_checksum(optional): Calculate and return SHA-256 checksum (default: True)max_retries(optional): Maximum retry attempts on failure (default: 3)
Returns a dictionary with artifact info including checksum.
example:
>> # Upload files matching patterns
>> result = artifacts.upload_artifact(
>> name="test-results",
>> patterns=["*.xml", "coverage/**"],
>> retention_days=7
>> )
# Output:
# Artifact 'test-results' uploaded successfully.
>> print(result)
# {'name': 'test-results', 'size': '12345', 'checksum': 'abc123...'}
>> # Upload specific paths
>> result = artifacts.upload_artifact(
>> name="build-output",
>> paths=["dist/", "build/app.js"]
>> )
GitHubArtifacts.download_artifact(artifact, is_extract=False, extract_dir=None, verify_checksum=False, expected_checksum=None, max_retries=3)¶
Downloads a given artifact as a zip file with optional extraction and integrity verification.
artifact: The artifact object (from get_artifacts() or get_artifact()).is_extract(optional): If True, extracts the contents of the zip.extract_dir(optional): Directory to extract to. Defaults to artifact_<artifact.name>.verify_checksum(optional): Calculate and print checksum for verification (default: False)expected_checksum(optional): Expected SHA-256 checksum to verify againstmax_retries(optional): Maximum retry attempts on failure (default: 3)
example:
>> file_path = artifacts.download_artifact(artifact)
# Output:
# Artifact 'running-tests' downloaded successfully.
>> # Download with checksum verification
>> file_path = artifacts.download_artifact(
>> artifact,
>> verify_checksum=True,
>> expected_checksum="abc123..."
>> )
# Output:
# Artifact 'running-tests' downloaded successfully.
# Checksum verified: abc123...
Extracting it:
>> folder = artifacts.download_artifact(artifact, is_extract=True)
# Output:
# Artifact 'running-tests' downloaded successfully.
# Folder 'artifact_running-tests' created with extracted contents.
GitHubArtifacts.delete_artifact(artifact, max_retries=3)¶
Deletes the given artifact from the repository with retry logic for robustness.
artifact: The artifact object to delete.max_retries(optional): Maximum retry attempts on failure (default: 3)
Returns True if deleted successfully, otherwise False.
example:
>> result = artifacts.delete_artifact(artifact)
# Output:
# Artifact 123456 (test-logs) deleted successfully.
Features¶
The artifact management system includes:
Pattern Glob Support: Use wildcards to select files for upload (e.g.,
*.log,build/**/*.js)Compression: Automatic ZIP compression with optimized settings
Multi-file Streaming: Efficient handling of multiple files
Integrity Checks: SHA-256 checksums for upload and download verification
Retention Configuration: Set custom retention periods for artifacts
Retry Logic: Automatic retry with exponential backoff for transient failures
Error Handling: Robust handling of large files and edge cases with detailed error messages
Artifact Patterns¶
Uploading Test Results¶
from pathlib import Path
from github_action_toolkit import GitHubArtifacts, info
def upload_test_results(results_dir: Path):
"""Upload all test result files as artifacts."""
artifacts = GitHubArtifacts()
# Upload with pattern matching
artifacts.upload_artifact(
name='test-results',
paths=[results_dir],
retention_days=30
)
info(f'Uploaded test results from {results_dir}')
Downloading from Previous Run¶
from github_action_toolkit import GitHubArtifacts, info
def download_previous_artifact(artifact_name: str, dest: str):
"""Download artifact from previous workflow run."""
artifacts = GitHubArtifacts()
# Get latest artifact with this name
artifact_list = artifacts.get_artifacts(name_pattern=artifact_name)
if not artifact_list:
info(f'No artifact found: {artifact_name}')
return None
latest = artifact_list[0]
artifacts.download_artifact(latest.id, dest)
info(f'Downloaded {artifact_name} to {dest}')
return dest
Conditional Artifact Upload¶
from github_action_toolkit import GitHubArtifacts, get_user_input_as
def upload_artifacts_if_enabled():
"""Only upload artifacts if configured."""
upload_artifacts = get_user_input_as(
'upload-artifacts',
bool,
default_value=True
)
if not upload_artifacts:
info('Artifact upload disabled')
return
artifacts = GitHubArtifacts()
artifacts.upload_artifact(
name='build-output',
paths=['dist/']
)