Skip to main content
Build Status Coveralls Project generated with PyScaffold

gerrit-to-platform

Gerrit to GitHub / GitLab (not yet available)

Gerrit hooks to allow using GitHub and GitLab as CI platforms.

To use, install the Gerrit hooks plugin and then symlink the hooks from the virtualenv that has the package installed.

You need to have a Python 3.11 or greater environment.

Repositories that use the CI platform must have full mirroring replication configured. In specific refs/* must be in the replication set and not refs/heads/*

To activate a given hook, symlink the installed hook in the gerrit hooks directory.

You need two configuration files:

  • ~gerrituser/.config/gerrit_to_platform/gerrit_to_platform.ini

  • ~gerrituser/.config/gerrit_to_platform/replication.config

The replication.config file should be a symlink to the standard Gerrit replication.config file

The gerrit_to_platform.ini file has the following format:

[mapping "comment-added"]
recheck = verify
remerge = merge

[github.com]
token = <a_token_that_allows_triggering_actions>

[gitlab.com]
token = <a_token_that_allows_triggering_workflows>

# Optional. The change visibility gate is enabled by default; only
# set this on Gerrit servers without anonymous REST read access.
[gerrit]
visibility_check = false

The comment-added mapping section is a key value pair for comment triggers to the corresponding workflow name or filename

Private and Restricted Changes

Before dispatching for patchset-created and comment-added events, gerrit-to-platform probes the change anonymously over the Gerrit REST API (GET <base>/changes/<number>). Gerrit answers HTTP 404 for changes the requester cannot see — private changes in particular — which matches what the platform-side service account and the replication mirror can access. When the change is unreadable the dispatch is skipped and the reason is logged; Gerrit fires a fresh event when the change is published, so no verification coverage is lost.

The probe fails open: network errors, timeouts and unexpected statuses all allow the dispatch to proceed, so a Gerrit REST outage can never block CI. change-merged events skip the probe because Gerrit refuses to submit private changes.

On Gerrit servers without anonymous REST read access every change would probe as HTTP 404, so operators of such servers must disable the gate with visibility_check = false in the [gerrit] section (see above).

GitHub Workflow Configuration

There are three hooks that gerrit-to-platform handles:

  • patchset-created (search filter: verify)

  • change-merged (search filter: merge)

  • comment-added (comment mapping for keyword to search filter)

Configuration for triggered workflows must meet the following requirements:

  • The workflow filename must contain ‘gerrit’

  • The workflow filename must contain the search filter

Required workflows (those that should run on all projects) must be part of the ORGANIZATION/.github magic repository. These workflow filenames must also contain ‘required’.

ex: .github/workflows/gerrit-required-verify.yaml

You can put standard workflows (non-required ones) into a project’s repository, in the .github directory. These should have filenames that include ‘gerrit’ and the search filter, as discussed above, but do not need anything beyond. They should never include ‘required’ in their filename.

ex: .github/workflows/gerrit-merge.yaml or .github/workflows/gerrit-sonar-novote-verify.yaml

Filename matching is a case-insensitive substring test (str.find), not a prefix or exact match: a workflow is selected when its filename contains both gerrit and the search filter anywhere in the name. The recommended naming convention is gerrit-<description>-<event>.yaml so that the gerrit- prefix opts the workflow into Gerrit dispatch and the trailing event keyword (verify, merge, or a custom comment keyword) selects the hook.

ex: gerrit-verify.yaml, gerrit-maven-merge.yaml, gerrit-release-merge.yaml

Because the match is a substring and gerrit-to-platform dispatches every matching workflow for an event, two cautions apply:

  • Choose names so that only the intended workflows match. For example, both gerrit-maven-merge.yaml and gerrit-release-merge.yaml contain merge and therefore both fire on every change-merged event.

  • A workflow that must not act on every event has to self-gate, for example by inspecting the changed files or GERRIT_EVENT_TYPE and exiting early when it does not apply.

For comment-added triggers the search filter is the value mapped to the keyword in the [mapping "comment-added"] section described above, so the workflow filename must contain that mapped filter. For example, with stage-release = stage a posted stage-release comment selects workflows whose filename contains both gerrit and stage, such as gerrit-maven-stage.yaml.

All workflows must have the following primary configuration:

---
name: Gerrit Verify

# yamllint disable-line rule:truthy
on:
  workflow_dispatch:
    inputs:
      GERRIT_BRANCH:
        description: 'Branch that change is against'
        required: true
        type: string
      GERRIT_CHANGE_ID:
        description: 'The ID for the change'
        required: true
        type: string
      GERRIT_CHANGE_NUMBER:
        description: 'The Gerrit number'
        required: true
        type: string
      GERRIT_CHANGE_URL:
        description: 'URL to the change'
        required: true
        type: string
      GERRIT_EVENT_TYPE:
        description: 'Gerrit event type'
        required: true
        type: string
      GERRIT_PATCHSET_NUMBER:
        description: 'The patch number for the change'
        required: true
        type: string
      GERRIT_PATCHSET_REVISION:
        description: 'The revision sha'
        required: true
        type: string
      GERRIT_PROJECT:
        description: 'Project in Gerrit'
        required: true
        type: string
      GERRIT_REFSPEC:
        description: 'Gerrit refspec of change'
        required: true
        type: string


concurrency:
  group: ${{ github.event.inputs.GERRIT_CHANGE_ID || github.run_id }}
  cancel-in-progress: true

jobs:
  <your_job_configurations>

Required workflows must have the following extra input:

TARGET_REPO:
  description: 'The target GitHub repository needing the required workflow'
  required: true
  type: string

ChatOps Workflow

Trigger GitHub Actions workflows directly from Gerrit by adding comments to your changes. This eliminates the need for manual workflow triggers and enables automated testing on-demand.

To trigger a workflow, add a comment to any Gerrit change using the pattern:

gha-<action> <workflow-name> <parameters>

For example:

gha-run csit-2n-perftest nic=intel-e810cq drv=avf

Common examples include:

gha-run csit-2n-perftest nic=intel-e810cq drv=avf
gha-run csit-3n-perftest mrrANDnic_intel-e810cqANDdrv_avfAND4c
gha-run csit-2n-mrr-weekly
gha-run csit-3n-mrr-daily nic=intel-x710
gha-run terraform-cdash-deploy env=production
gha-run terraform-infra-update region=us-west
gha-run vpp-build type=release arch=x86_64
gha-run vpp-verify compiler=gcc
gha-run hicn-verify arch=amd64
gha-run cicn-build type=debug
gha-run hc2vpp-integration-test
gha-run hc2vpp-verify

Specify parameters in two formats:

  1. Key=Value format (recommended):

    gha-run csit-2n-perftest nic=intel-e810cq drv=avf framesize=64
  2. AND-separated format (legacy support):

    gha-run csit-2n-perftest mrrANDnic_intel-e810cqANDdrv_avfAND4c

Cooldown Period: To prevent workflow spam, there is a 5-minute cooldown between commands for the same workflow on the same change. If you trigger a workflow and need to run it again, wait 5 minutes before commenting.

Troubleshooting: If your command doesn’t trigger a workflow:

  • Verify the command starts with gha- followed by the action and workflow name

  • Check that the workflow name matches a supported pattern for your project

  • Wait 5 minutes if you triggered the same workflow on this change within the last 5 minutes

  • Review GitHub Actions logs for error messages

Workflow Configuration: Name workflows that respond to ChatOps commands comment-handler and include a GERRIT_COMMENT input that receives the full command line. The workflow then parses the command to determine which handler to execute. See gerrit-comment-handler.yaml for a complete example.

Workflow Migration Guide

This section helps teams migrate from vanilla GitHub workflows (or Jenkins jobs) to Gerrit-integrated GitHub Actions workflows. The examples/workflows/ directory contains annotated example workflows.

Example Workflows

Four example workflows progress from a standard GitHub workflow to increasingly Gerrit-integrated patterns:

  1. examples/workflows/github-vanilla-verify.yaml — A pure GitHub workflow with no Gerrit dependencies. Serves as the baseline showing standard pull_request, push, and workflow_dispatch triggers with actions/checkout.

  2. examples/workflows/gerrit-verify.yaml — The Gerrit-integrated verify counterpart. Demonstrates the clear-vote → build → vote pattern with checkout-gerrit-change-action and all nine GERRIT_* inputs.

  3. examples/workflows/gerrit-merge.yaml — The Gerrit-integrated post-merge workflow. Shows comment-only mode (no voting on merged changes), standard actions/checkout, and the replication delay pattern.

  4. examples/workflows/gerrit-verify-manual-dispatch.yaml — A verify workflow that supports both Gerrit dispatch and manual runs from the GitHub Actions UI. Demonstrates optional inputs, conditional Gerrit jobs, and adaptive checkout strategy.

Verify vs. Merge Patterns

Gerrit workflows fall into two fundamental patterns based on the hook that triggers them:

Verify workflows (patchset-created hook, search filter: verify):

  • Test unmerged changes (open Gerrit patchsets)

  • Must vote on the change: Verified +1 (success) or Verified -1 (failure)

  • Clear any previous vote at the start of the run

  • Must use checkout-gerrit-change-action — the standard actions/checkout cannot see unmerged Gerrit change refs (e.g., refs/changes/40/11540/1) on the GitHub mirror

  • Job structure: clear-votebuild-and-testvote

Merge workflows (change-merged hook, search filter: merge):

  • Run after a change lands on the target branch

  • Cannot vote on a merged/closed change — use comment-only: "true" to post status comments instead

  • Use standard actions/checkout — the merged code is already on the branch HEAD in the GitHub mirror

  • Add a replication delay (sleep 10s) before checkout to allow the Gerrit replication plugin to sync the merged commit to GitHub

  • Job structure: notify (comment-only) → build-and-publishreport-status (comment-only)

Checkout Rules

Choosing the correct checkout action is the single most important difference between verify and merge workflows:

Workflow Type

Checkout Action

Why

Verify

lfreleng-actions/checkout-gerrit-change-action

Fetches the unmerged change ref from the Gerrit server (or GitHub mirror if replicated). actions/checkout will not find these refs.

Merge

actions/checkout with ref: ${{ inputs.GERRIT_BRANCH }}

The change already exists in the branch. No special ref fetching required. Add a replication delay before checkout.

Manual dispatch

actions/checkout (no ref override needed)

Checks out the branch selected in the GitHub UI (github.ref).

Voting Rules

Workflow Type

Voting

Details

Verify

Full voting

clear at start, success/failure/cancelled at end. Uses gerrit-review-action with vote-type.

Merge

Comment-only

Set comment-only: "true" on all gerrit-review-action steps. Attempting to vote on a merged change will fail.

Advisory verify

Comment-only

Non-blocking verify checks can use comment-only: "true" to post results without affecting the Verified label. Add a comment-only input to toggle this behavior (see production workflow gerrit-required-info-yaml-verify.yaml for an example).

Concurrency Groups

Gerrit workflows should key their concurrency group on GERRIT_CHANGE_ID:

concurrency:
  group: ${{ github.event.inputs.GERRIT_CHANGE_ID || github.run_id }}
  cancel-in-progress: true

This ensures that pushing a new patchset to the same Gerrit change cancels any in-progress run for the previous patchset. The github.run_id fallback prevents issues when inputs are absent (e.g., manual dispatch).

Replication Delay

Gerrit-to-GitHub replication is asynchronous. Workflows should include a brief sleep (typically 10 seconds) to allow refs to propagate to the GitHub mirror:

  • Verify workflows: The clear-vote job includes sleep 10s after clearing the vote. Because the build job waits for clear-vote via needs:, the delay fits in naturally.

  • Merge workflows: The notify job includes sleep 10s after posting the start comment. This gives the merged commit time to appear on the mirror before the build job runs actions/checkout.

The checkout-gerrit-change-action also accepts a delay parameter for extra delay, though setting delay: "0s" is common when a preceding job already includes the replication sleep.

Manual Dispatch Bypass Pattern

For workflows where running from the GitHub Actions UI is valuable (debugging, on-demand checks, advisory scans), the manual dispatch bypass pattern adds:

  1. A MANUAL_DISPATCH boolean input (default: false)

  2. All GERRIT_* inputs marked required: false with empty defaults

  3. Conditional if: guards on Gerrit-specific jobs (clear-vote, vote)

  4. Dual checkout steps — one for Gerrit dispatch, one for manual dispatch — with if: conditions keyed on GERRIT_REFSPEC

When gerrit_to_platform dispatches the workflow, it populates all inputs and MANUAL_DISPATCH defaults to false, so the workflow behaves identically to a standard Gerrit verify. When a developer clicks “Run workflow” in the GitHub UI, the workflow skips Gerrit jobs and uses standard checkout.

See examples/workflows/gerrit-verify-manual-dispatch.yaml for the complete annotated example.

Required (Organization-Wide) Workflows

Workflows that must run on every repository in the organization live in the ORGANIZATION/.github magic repository. These have extra requirements:

  • The filename must include required (e.g., gerrit-required-verify.yaml)

  • An extra TARGET_REPO input tells the workflow which repository to check out:

    TARGET_REPO:
      description: 'The target GitHub repository needing the required workflow'
      required: true
      type: string
  • Set the checkout-gerrit-change-action repository parameter to ${{ inputs.TARGET_REPO }}

workflow_dispatch Input Limit

GitHub enforced a hard limit of 10 inputs for workflow_dispatch events until December 2025. With 9 standard GERRIT_* inputs, this left 1 slot for custom workflow parameters — a severe constraint for teams that required extra inputs.

In December 2025, GitHub raised this limit from 10 to 25 inputs. This change relieves the constraint, leaving 16 slots for custom parameters alongside the 9 GERRIT_* inputs. See the GitHub changelog announcement for details.

For detailed background on this constraint and alternative workarounds (such as using repository_dispatch with unlimited client_payload fields), see docs/GITHUB_WORKFLOW_INPUT_LIMIT_SOLUTION.md.

Companion GitHub Actions

Two GitHub Actions are essential for Gerrit-integrated workflows:

gerrit-review-action (lfreleng-actions/gerrit-review-action):

Posts votes (Verified +1/-1) and comments on Gerrit changes via SSH. Supports vote types: clear, success, failure, cancelled. Set comment-only: "true" for merge workflows and advisory checks.

checkout-gerrit-change-action (lfreleng-actions/checkout-gerrit-change-action):

Fetches unmerged Gerrit change refs (e.g., refs/changes/YY/NNYY/Z) from the GitHub mirror or falls back to the Gerrit server directly. Required for all verify workflows because actions/checkout cannot see unmerged refs.

Quick Reference: Vanilla → Gerrit Migration Checklist

When converting a standard GitHub workflow to a Gerrit-integrated one:

#

Task

Notes

1

Replace triggers with workflow_dispatch + 9 GERRIT_* inputs

Remove pull_request, push triggers entirely

2

Set concurrency group to GERRIT_CHANGE_ID

Replaces github.head_ref or branch-based grouping

3

Add clear-vote job at the start (verify)

Resets previous Verified votes; includes replication sleep

4

Replace actions/checkout (verify)

Use checkout-gerrit-change-action with gerrit-refspec, gerrit-project, gerrit-url, and ref

5

Add vote job at the end (verify)

Must use if: ${{ always() }} to report even on failure

6

For merge workflows, use comment-only: "true"

Keep actions/checkout but add replication sleep before it

7

Name the file appropriately

Must contain gerrit and the search filter (verify or merge)

8

Configure repository variables and secrets

GERRIT_SERVER, GERRIT_SSH_USER, GERRIT_SSH_PRIVKEY, GERRIT_KNOWN_HOSTS, GERRIT_URL

Making Changes & Contributing

This project uses pre-commit, please make sure to install it before making any changes:

pip install pre-commit
cd gerrit_to_platform
pre-commit install
pre-commit install -t commit-msg

Don’t forget to tell your contributors to also install and use pre-commit.

Note

PyScaffold 4.4 provided the initial project setup. For details and usage information on PyScaffold see https://pyscaffold.org/.

Download files

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

Source Distribution

gerrit_to_platform-0.4.0.tar.gz (98.9 kB view details)

Uploaded Source

Built Distribution

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

gerrit_to_platform-0.4.0-py3-none-any.whl (41.7 kB view details)

Uploaded Python 3

File details

Details for the file gerrit_to_platform-0.4.0.tar.gz.

File metadata

  • Download URL: gerrit_to_platform-0.4.0.tar.gz
  • Upload date:
  • Size: 98.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for gerrit_to_platform-0.4.0.tar.gz
Algorithm Hash digest
SHA256 72bcdc79882901a0bb3f0098bf836279a6f80a883c2c32adc0e3c2b1a0b37e45
MD5 96e8b2626ea2c3024ff85f9fc50b9b8a
BLAKE2b-256 19c464701bd8d51538ba88e99bdd4253da17e5f111e4b47a434e461cc078b1c5

See more details on using hashes here.

Provenance

The following attestation bundles were made for gerrit_to_platform-0.4.0.tar.gz:

Publisher: release.yaml on lfit/releng-gerrit_to_platform

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gerrit_to_platform-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for gerrit_to_platform-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9c6c218da6e6c3cba99f6d142e75b927f6b1af283e465e44e9a0c4ba7b63bae5
MD5 40ab3df7d11ed32cf0ede8ed5b79f375
BLAKE2b-256 05e1b5a2cafb8626cd8309db94a46d368dfbe5523e6b1fcc12d976d0f89d6c87

See more details on using hashes here.

Provenance

The following attestation bundles were made for gerrit_to_platform-0.4.0-py3-none-any.whl:

Publisher: release.yaml on lfit/releng-gerrit_to_platform

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 files

0.3.1

2 files

0.3.0

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page