Gathers comprehensive metadata about the GitHub repository, including repository information, commit details, branch/tag information, pull request context, event detection, and more for use in other actions and workflows.
This action provides a rich set of metadata outputs to help you make intelligent decisions in your GitHub Actions workflows. It automatically detects which event triggered the workflow and extracts relevant information.
- 📦 Repository Information: Owner, name, visibility
- 🔀 Branch/Tag Detection: Identify branches, tags, and default branch
- 📝 Commit Metadata: SHA, message, author
- 🔄 Pull Request Context: PR number, source/target branches, fork detection
- 🎯 Event Type Detection: Automatically detect push, PR, release, schedule, etc.
- 🔑 Cache Key Generation: Smart cache keys for workflow optimization
- 📄 Changed Files: List of files changed in PRs and pushes
- 📋 JSON Output: All metadata in a single JSON object
- 📄 YAML Output: All metadata in YAML format
- 🔍 Debug Mode: Verbose logging for troubleshooting
- 📋 Gerrit Integration: Automatic detection and processing of Gerrit change metadata
steps:
- name: "Checkout repository"
uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for changed files detection
- name: "Repository metadata"
id: repository-metadata
uses: lfreleng-actions/repository-metadata-action@main
with:
debug: false # Set to true for verbose output
github_token: ${{ secrets.GITHUB_TOKEN }} # For changed files
- name: "Use metadata"
run: |
echo "Repo: ${{ steps.repository-metadata.outputs.repository_full_name }}"
echo "Branch: ${{ steps.repository-metadata.outputs.branch_name }}"
echo "Commit: ${{ steps.repository-metadata.outputs.commit_sha_short }}"
echo "Is PR: ${{ steps.repository-metadata.outputs.is_pull_request }}"
echo "Cache: ${{ steps.repository-metadata.outputs.cache_key }}"| Variable Name | Description | Required | Default |
|---|---|---|---|
| debug | Enable debug mode for verbose output | No | false |
| github_token | GitHub token for API access (changed files) | No | ${{ github.token }} |
| github_summary | Generate GitHub execution environment summary in GITHUB_STEP_SUMMARY | No | false |
| gerrit_summary | Generate Gerrit parameters summary in GITHUB_STEP_SUMMARY (independent of github_summary) | No | true |
| files_summary | Generate changed files summary in GITHUB_STEP_SUMMARY (independent of github_summary) | No | false |
| gerrit_include_comment | Include Gerrit comment in summaries and JSON/YAML outputs (may contain sensitive data; use with care) | No | false |
| artifact_upload | Upload metadata as workflow artifact | No | true |
| artifact_formats | Comma-separated list of formats to upload (json, yaml) | No | json,yaml |
| change_detection | Changed files detection method: 'git' or 'github_api' | No | (auto) |
| git_fetch_depth | Depth for git fetch --deepen in shallow clones | No | 15 |
| Variable Name | Description |
|---|---|
| repository_owner | Name of the GitHub organization |
| repository_name | Name of the GitHub repository |
| repository_full_name | Full repository name (owner/name) |
| is_public | Returns true if the repository is public |
| is_private | Returns true if the repository is private |
| Variable Name | Description |
|---|---|
| event_name | The name of the event that triggered the workflow |
| tag_push_event | Returns true if a version tag push triggered the event |
| is_tag_push | Returns true if the event is a tag push |
| is_branch_push | Returns true if the event is a branch push |
| is_pull_request | Returns true if the event is a pull request |
| is_release | Returns true if the event is a release |
| is_schedule | Returns true if the event runs on a schedule |
| is_workflow_dispatch | Returns true if the event is manually triggered |
| Variable Name | Description |
|---|---|
| branch_name | Returns the branch name (empty for tag pushes) |
| tag_name | Returns the tag name (empty if not a tag) |
| is_default_branch | Returns true if running on the default branch |
| is_main_branch | Returns true if running on main or master branch |
| Variable Name | Description |
|---|---|
| commit_sha | Full commit SHA |
| commit_sha_short | Short commit SHA (first 7 characters) |
| commit_message | Commit message title |
| commit_author | Commit author name |
| Variable Name | Description |
|---|---|
| pr_number | Pull request number (empty if not a PR) |
| pr_source_branch | Pull request source branch (head ref) |
| pr_target_branch | Pull request target branch (base ref) |
| is_fork | Returns true if pull request is from a fork |
| pr_commits_count | Number of commits in the pull request |
| Variable Name | Description |
|---|---|
| actor | GitHub actor (user who triggered the workflow) |
| actor_id | GitHub actor ID |
| Variable Name | Description |
|---|---|
| cache_key | Generated cache key based on repository and commit |
| cache_restore_key | Generated cache restore key prefix |
| Variable Name | Description |
|---|---|
| changed_files | List of changed files (newline-separated) |
| changed_files_count | Number of changed files |
| changed_files_added | List of added files (newline-separated) |
| changed_files_added_count | Number of added files |
| changed_files_modified | List of modified files (newline-separated) |
| changed_files_modified_count | Number of modified files |
| changed_files_removed | List of removed files (newline-separated) |
| changed_files_removed_count | Number of removed files |
| Variable Name | Description |
|---|---|
| artifact_path | Path to the metadata artifact files (if uploaded) |
| artifact_suffix | Unique 4-character alphanumeric suffix for artifact naming |
Note: Changed files detection requires checking out the repository
with git history. For pull requests, it works best with the github_token
input provided.
| Variable Name | Description |
|---|---|
| gerrit_json | Gerrit metadata as JSON (from input or built from gerrit_to_platform inputs) |
Note: Gerrit outputs populate when the workflow triggers via
workflow_dispatch with Gerrit inputs.
The gerrit_json output provides a consistent JSON structure regardless of
input method:
- If
gerrit_jsoninput contains valid JSON, it passes through (with thecommentfield removed unless you enablegerrit_include_comment) - If
gerrit_jsoninput contains invalid or missing JSON, the action builds JSON from gerrit_to_platform inputs - Downstream consumers always reference the same output
Example gerrit_json:
{
"branch": "main",
"change_id": "I1234567890abcdef1234567890abcdef12345678",
"change_number": "12345",
"change_url": "https://gerrit.example.com/r/c/test-project/+/12345",
"event_type": "patchset-created",
"patchset_number": "3",
"patchset_revision": "abcdef1234567890abcdef1234567890abcdef12",
"project": "test-project",
"refspec": "refs/changes/45/12345/3",
}| Variable Name | Description |
|---|---|
| metadata_json | All metadata as a JSON object |
| metadata_yaml | All metadata as a YAML object |
Both JSON and YAML outputs contain all metadata in structured formats:
JSON Format:
{
"repository": {
"owner": "owner-name",
"name": "repo-name",
"full_name": "owner-name/repo-name",
"is_public": true,
"is_private": false
},
"event": {
"name": "push",
"is_tag_push": false,
"is_branch_push": true,
"is_pull_request": false,
"is_release": false,
"is_schedule": false,
"is_workflow_dispatch": false,
"tag_push_event": false
},
"ref": {
"branch_name": "main",
"tag_name": null,
"is_default_branch": true,
"is_main_branch": true
},
"commit": {
"sha": "abc123...",
"sha_short": "abc123",
"message": "Commit message",
"author": "Author Name"
},
"pull_request": {
"number": null,
"source_branch": null,
"target_branch": null,
"commits_count": null,
"is_fork": false
},
"actor": {
"name": "username",
"id": 12345
},
"cache": {
"key": "owner-repo-main-abc123",
"restore_key": "owner-repo-main-"
},
"changed_files": {
"count": 0,
"files": null
}
}YAML Format:
repository:
owner: owner-name
name: repo-name
full_name: owner-name/repo-name
is_public: true
is_private: false
event:
name: push
is_tag_push: false
is_branch_push: true
is_pull_request: false
is_release: false
is_schedule: false
is_workflow_dispatch: false
tag_push_event: false
ref:
branch_name: main
tag_name: null
is_default_branch: true
is_main_branch: true
commit:
sha: abc123...
sha_short: abc123
message: Commit message
author: Author Name
pull_request:
number: null
source_branch: null
target_branch: null
commits_count: null
is_fork: false
actor:
name: username
id: 12345
cache:
key: owner-repo-main-abc123
restore_key: owner-repo-main-
changed_files:
count: 0
files: nullBy default, the action uploads metadata as a workflow artifact. Each invocation generates a unique artifact name to avoid conflicts when calling the action more than once in the same workflow.
Artifact Naming Format: repository-metadata-<job-name>-<suffix>
Where <suffix> is a randomly generated 4-character alphanumeric string
(e.g., a3f9, x2k5).
Examples:
repository-metadata-tests-a3f9repository-metadata-build-x2k5repository-metadata-deploy-7n4m
The artifact contains (by default):
repository-metadata.json- Compact JSON formatrepository-metadata-pretty.json- Pretty-printed JSON for human readabilityrepository-metadata.yaml- YAML format
Customize artifact formats:
# Upload JSON format
- uses: lfreleng-actions/repository-metadata-action@main
with:
artifact_formats: json
# Upload YAML format
- uses: lfreleng-actions/repository-metadata-action@main
with:
artifact_formats: yaml
# Upload both (default)
- uses: lfreleng-actions/repository-metadata-action@main
with:
artifact_formats: json,yamlDisable artifact upload:
- uses: lfreleng-actions/repository-metadata-action@main
with:
artifact_upload: falseThe action supports two methods for detecting changed files in pull requests:
When you provide github_token, the action uses the GitHub API. Otherwise,
it falls back to git-based detection.
You can force a specific detection method using the change_detection input:
Git-based detection (works offline, requires git history):
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for git-based detection
- uses: lfreleng-actions/repository-metadata-action@main
with:
change_detection: gitGitHub API-based detection (requires token):
- uses: lfreleng-actions/repository-metadata-action@main
with:
change_detection: github_api
github_token: ${{ secrets.GITHUB_TOKEN }}The action automatically handles shallow clones by fetching the base branch when needed for accurate file change detection.
When using git-based detection with shallow clones, the action may need to fetch more history to find the common ancestor between the PR branch and the base branch. You can configure the fetch depth:
- uses: lfreleng-actions/repository-metadata-action@main
with:
change_detection: git
git_fetch_depth: 15 # Default: 15 commitsWhen to adjust:
- Increase (e.g., 30-50) if you have PRs with more than 15 commits
- Decrease (e.g., 5-10) for faster fetches if PRs are typically small
- Most PRs have fewer than 15 commits, making the default appropriate for most use cases
jobs:
metadata:
runs-on: ubuntu-latest
outputs:
is_release: ${{ steps.meta.outputs.is_release }}
is_main_branch: ${{ steps.meta.outputs.is_main_branch }}
steps:
- uses: actions/checkout@v4
- id: meta
uses: lfreleng-actions/repository-metadata-action@main
deploy:
needs: metadata
if: needs.metadata.outputs.is_release == 'true'
runs-on: ubuntu-latest
steps:
- run: echo "Deploying release..."
build:
needs: metadata
if: needs.metadata.outputs.is_main_branch == 'true'
runs-on: ubuntu-latest
steps:
- run: echo "Building from main branch..."steps:
- uses: actions/checkout@v4
- id: metadata
uses: lfreleng-actions/repository-metadata-action@main
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ steps.metadata.outputs.cache_key }}-pip
restore-keys: |
${{ steps.metadata.outputs.cache_restore_key }}-pipsteps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: metadata
uses: lfreleng-actions/repository-metadata-action@main
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: "Check if docs changed"
if: steps.metadata.outputs.is_pull_request == 'true'
run: |
changed="${{ steps.metadata.outputs.changed_files }}"
if echo "$changed" | grep -q "docs/"; then
echo "This PR modifies documentation files"
fi
- name: "Check PR commit count"
if: steps.metadata.outputs.is_pull_request == 'true'
run: |
commit_count="${{ steps.metadata.outputs.pr_commits_count }}"
if [ "$commit_count" -gt 10 ]; then
echo "⚠️ This PR has $commit_count commits - consider squashing"
else
echo "✅ This PR has $commit_count commits"
fisteps:
- uses: actions/checkout@v4
- id: metadata
uses: lfreleng-actions/repository-metadata-action@main
- name: "Process metadata with jq"
env:
METADATA: ${{ steps.metadata.outputs.metadata_json }}
run: |
echo "$METADATA" | jq '.repository.owner'
echo "$METADATA" | jq '.commit.sha_short'
echo "$METADATA" | jq '.event | to_entries[] | select(.value == true)'steps:
- uses: actions/checkout@v4
- id: metadata
uses: lfreleng-actions/repository-metadata-action@main
- name: "Process metadata with yq"
env:
METADATA: ${{ steps.metadata.outputs.metadata_yaml }}
run: |
echo "$METADATA" | yq eval '.repository.owner'
echo "$METADATA" | yq eval '.commit.sha_short'
echo "$METADATA" | yq eval '.ref.branch_name'Enable debug mode to see detailed information about the metadata extraction:
steps:
- id: metadata
uses: lfreleng-actions/repository-metadata-action@main
with:
debug: trueThis action provides comprehensive support for Gerrit-triggered workflows through automatic detection and processing of Gerrit change metadata.
on:
workflow_dispatch:
inputs:
gerrit_json:
description: 'Consolidated Gerrit metadata'
required: false
type: string
jobs:
process-change:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 'Gather metadata'
id: metadata
uses: lfreleng-actions/repository-metadata-action@main
with:
gerrit_summary: 'true'
github_summary: 'true'
gerrit_include_comment: 'false'
- name: 'Use Gerrit data'
run: |
echo "Change: ${{ steps.metadata.outputs.gerrit_json }}"- ✅ Dual Input Support: Accepts both consolidated
gerrit_jsonand legacy gerrit_to_platform inputs - ✅ Automatic Detection: Reads from workflow event payload - no manual configuration needed
- ✅ Priority Handling:
gerrit_jsontakes precedence over individual variables - ✅ Fallback Support: Falls back to legacy variables if JSON is invalid
- ✅ Independent Summary Controls: Enable or disable
github_summary,gerrit_summary, andfiles_summaryindependently to control what appears in GITHUB_STEP_SUMMARY - ✅ JSON/YAML Export: Includes Gerrit metadata in artifact outputs (all fields always present, even if empty)
- ✅ Secure by Default: Comment field excluded from outputs unless
explicitly enabled with
gerrit_include_comment: 'true'
The action provides three independent summary controls:
github_summary: Controls GitHub execution environment summary (repository, event, commit, PR, actor, cache). Default:falsegerrit_summary: Controls Gerrit parameters summary (change info, patchset details). Default:truefiles_summary: Controls changed files summary (added/modified/removed files). Default:false
Smart Filtering: All summaries automatically filter out empty values. Tables display rows with populated data, and the action hides entire sections when all values are empty. This keeps the output clean and relevant to your workflow context.
You can enable them independently or together:
# GitHub summary alone
with:
github_summary: 'true'
# Gerrit summary alone
with:
gerrit_summary: 'true'
# Files summary alone
with:
files_summary: 'true'
# All summaries
with:
github_summary: 'true'
gerrit_summary: 'true'
files_summary: 'true'Note: For backward compatibility, the action also supports the deprecated
GENERATE_SUMMARY environment variable name as a fallback when
GITHUB_SUMMARY is not set. We recommend using the github_summary
input in your workflows going forward.
- The action uses
set -euo pipefailfor robust error handling - For pull requests, changed files detection works best when you check out
the repository with full git history (
fetch-depth: 0) - The
tag_push_eventoutput specifically detects version tags that start with 'v' followed by numbers (e.g., v1.0.0, v2.1.3) - Repository visibility detection requires the
GITHUB_REPOSITORY_VISIBILITYenvironment variable, which may not be available in all contexts - The
github_tokeninput is optional but recommended for pull request changed files detection - Exclude sensitive Gerrit inputs (e.g., comment) from summaries and JSON/YAML
outputs by default. To include them, set
gerrit_include_comment: 'true'in trusted contexts. - For testing, inject mock workflow payloads by setting
GITHUB_EVENT_PATH_OVERRIDEto a JSON file path in tests. Do not use this in production workflows; use this in CI/testing to simulateworkflow_dispatchinputs.
Apache-2.0
Contributions are welcome! Please ensure all changes pass the pre-commit hooks and tests.