Skip to content

lfreleng-actions/repository-metadata-action

Repository files navigation

🛠️ Repository Metadata

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.

repository-metadata-action

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.

Features

  • 📦 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

Usage Example

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 }}"

Inputs

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

Outputs

Repository Outputs

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

Event Type Detection Outputs

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

Branch and Tag Outputs

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

Commit Outputs

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

Pull Request Outputs

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

Actor Outputs

Variable Name Description
actor GitHub actor (user who triggered the workflow)
actor_id GitHub actor ID

Cache Outputs

Variable Name Description
cache_key Generated cache key based on repository and commit
cache_restore_key Generated cache restore key prefix

Changed Files Outputs

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

Artifact Outputs

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.

Gerrit Outputs

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_json input contains valid JSON, it passes through (with the comment field removed unless you enable gerrit_include_comment)
  • If gerrit_json input 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",
}

JSON and YAML Outputs

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: null

Artifact Upload

By 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-a3f9
  • repository-metadata-build-x2k5
  • repository-metadata-deploy-7n4m

The artifact contains (by default):

  • repository-metadata.json - Compact JSON format
  • repository-metadata-pretty.json - Pretty-printed JSON for human readability
  • repository-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,yaml

Disable artifact upload:

- uses: lfreleng-actions/repository-metadata-action@main
  with:
    artifact_upload: false

Changed Files Detection

The action supports two methods for detecting changed files in pull requests:

Automatic (Default)

When you provide github_token, the action uses the GitHub API. Otherwise, it falls back to git-based detection.

Explicit Method Selection

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: git

GitHub 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.

Git Fetch Depth Configuration

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 commits

When 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

Advanced Examples

Conditional Job Execution Based on Event Type

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..."

Using Cache Keys

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 }}-pip

Processing Changed Files

steps:
  - 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"
      fi

Using JSON Output for Complex Logic

steps:
  - 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)'

Using YAML Output

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'

Debug Mode

Enable debug mode to see detailed information about the metadata extraction:

steps:
  - id: metadata
    uses: lfreleng-actions/repository-metadata-action@main
    with:
      debug: true

Gerrit Integration

This action provides comprehensive support for Gerrit-triggered workflows through automatic detection and processing of Gerrit change metadata.

Quick Start

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 }}"

Gerrit Features

  • Dual Input Support: Accepts both consolidated gerrit_json and legacy gerrit_to_platform inputs
  • Automatic Detection: Reads from workflow event payload - no manual configuration needed
  • Priority Handling: gerrit_json takes 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, and files_summary independently 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'

Summary Output Control

The action provides three independent summary controls:

  • github_summary: Controls GitHub execution environment summary (repository, event, commit, PR, actor, cache). Default: false
  • gerrit_summary: Controls Gerrit parameters summary (change info, patchset details). Default: true
  • files_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.

Notes

  • The action uses set -euo pipefail for 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_event output 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_VISIBILITY environment variable, which may not be available in all contexts
  • The github_token input 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_OVERRIDE to a JSON file path in tests. Do not use this in production workflows; use this in CI/testing to simulate workflow_dispatch inputs.

License

Apache-2.0

Contributing

Contributions are welcome! Please ensure all changes pass the pre-commit hooks and tests.

About

Gathers metadata about the Github repository for use in other actions

Resources

License

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors