Release Notes

v0.4.0

New Features

  • Added a centralised, opt-in logging framework (gerrit_to_platform._logging) that operators can configure via G2P_LOG_* environment variables or a new [logging] section in gerrit_to_platform.ini. Default behaviour is unchanged (WARNING to stderr).

  • Logging supports a human-readable text format and a one-object- per-line JSON format (schema_version "1") suitable for aggregation in Loki / ELK / GitHub Actions log artefacts.

  • Each hook invocation carries a short correlation id, attached to every log line as cid=…. The id can be inherited from a parent process (e.g. the gerrit-action hook wrapper) by setting correlation_id_env to the relevant env-var name.

  • Hook entry-points (patchset-created, comment-added, change-merged) and the find_and_dispatch lifecycle now emit structured hook=…, platform detected, workflow lookup, dispatch attempt, dispatch success/failure and hook=… exit elapsed_ms=… lines so operators can diagnose ephemeral container deployments (Docker, GitHub-CI sandboxes) without source access.

  • The GitHub client wrapper logs every workflow dispatch and workflows-list call with timing, owner/repo and outcome.

  • A RedactingFilter is attached to every handler installed by configure() and scrubs GitHub token shapes, Authorization headers, token= query-string parameters and labelled token=/secret=/password= values from log records before any handler sees them.

  • Added four annotated example workflows in examples/workflows/ demonstrating how to build Gerrit-integrated GitHub Actions workflows:

    • github-vanilla-verify.yaml — Baseline GitHub workflow (no Gerrit)

    • gerrit-verify.yaml — Gerrit verify pattern with vote lifecycle and checkout-gerrit-change-action

    • gerrit-merge.yaml — Post-merge pattern using comment-only mode and standard actions/checkout

    • gerrit-verify-manual-dispatch.yaml — Hybrid pattern supporting both Gerrit dispatch and manual runs from the GitHub Actions UI

  • Added a Workflow Migration Guide to the README covering:

    • Verify vs. merge workflow patterns and when to use each

    • Checkout rules (checkout-gerrit-change-action vs actions/checkout)

    • Voting rules (full voting, comment-only, advisory modes)

    • Concurrency groups keyed on GERRIT_CHANGE_ID

    • Replication delay best practices

    • Manual dispatch bypass pattern for advisory workflows

    • Required (organization-wide) workflow configuration

    • Companion GitHub Actions (gerrit-review-action, checkout-gerrit-change-action)

    • Vanilla-to-Gerrit migration checklist

Known Issues

Upgrade Notes

  • No action is required for existing deployments: the framework is backwards-compatible at default verbosity. See docs/LOGGING.md for the new operator-facing configuration surface.

  • No operator action required. Existing deployments that did not trigger this crash (because their replication.config happened to keep fetch to a single line per remote) see no behaviour change. Deployments that did crash after every hook event — notably any pull-replication setup mirrored from a Gerrit source — will start dispatching workflows successfully after this release.

  • Behaviour for Gerrit servers that emit the legacy triplet shape is unchanged. Servers that emit the modern compact shape (Gerrit 3.x and later, or any older server configured to use the new shape) will start successfully dispatching workflows after this release; no operator action is required.

  • get_change_id now raises ValueError instead of IndexError for unrecognised input, which makes triage easier when inspecting hook tracebacks.

  • Operators of Gerrit servers that do not allow anonymous REST read access (where every change would probe as HTTP 404) must disable the new visibility gate in gerrit_to_platform.ini:

    [gerrit]
    visibility_check = false
    

    No action is required for servers with standard anonymous read access.

Bug Fixes

  • Fix configparser.DuplicateOptionError raised from every hook invocation when replication.config contains multi-valued fetch = ... refspecs under a single [remote "..."] section. This is the canonical shape Gerrit’s pull-replication plugin writes (and is valid git-config syntax for representing a list), but Python’s configparser defaults to strict=True and refuses to parse repeated keys. get_config() now constructs the parser with strict=False, which allows the multi-valued keys through with “last value wins” semantics. g2p only reads the single-valued url, authgroup and remotenamestyle keys from the remote sections, never the multi-valued fetch key, so the relaxed semantics have no functional impact.

  • Fixed documentation typo in README.rst where the [mapping "comment-added"] configuration section was incorrectly documented as [mapping "content-added"]. The code correctly reads comment-added (via get_mapping("comment-added")), so this was a documentation-only error. Operators copying the documented section name would have created a configuration section that was never read, causing comment-added triggers such as recheck, remerge, and custom keywords like stage-release to silently no-op.

  • Fix IndexError: list index out of range raised from every hook invocation against Gerrit 3.x servers that pass the modern compact --change argument (<URL-encoded project>~<number>, e.g. ccsdk%2Fapps~1). The previous get_change_id implementation only matched the legacy triplet form (project~branch~Iabc123...) and crashed for anything else, dropping every patchset-created, comment-added and change-merged event before workflow dispatch could run.

  • get_change_id now returns the legacy I... Change-Id when the legacy triplet form is supplied, and returns the modern compact project~number identifier verbatim otherwise. The compact form is still a unique, stable identifier per change and works as a GERRIT_CHANGE_ID workflow input (e.g. for concurrency.group keys).

  • Workflow dispatch no longer fires for changes the platform-side service account cannot read. Previously patchset-created (and comment-added) dispatched verify workflows unconditionally, including for private Gerrit changes. Private change refs are not replicated to the platform mirrors, so every such dispatch failed immediately (fatal: Not found: <change number>) and spammed the change owner and the releng mailing lists with failure notifications for work that was never ready for review.

    find_and_dispatch now probes the change anonymously over the Gerrit REST API before dispatching (GET <base>/changes/<number>). Gerrit answers HTTP 404 for changes the requester cannot see, which matches what the platform-side account and the replication mirror can access. When the change is unreadable, the dispatch is skipped and the reason is logged; a fresh hook event fires 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 entirely because Gerrit refuses to submit private changes.

Other Notes

  • Enhanced workflow filename matching documentation in README.rst to clarify the selection behaviour implemented by github.filter_workflows. The existing “must contain ‘gerrit’ and the search filter” requirement is now supplemented with:

    • The test is a case-insensitive substring match (str.find), not a prefix or exact match.

    • gerrit-to-platform dispatches all workflows that match an event, not just one.

    • Recommended naming convention is gerrit-<description>-<event>.yaml (e.g. gerrit-maven-merge.yaml, gerrit-verify.yaml).

    • Caution that workflows which must not act on every event have to self-gate (e.g. by inspecting changed files or GERRIT_EVENT_TYPE).

    • Example showing comment-added keyword mapping to workflow filename (e.g. stage-release = stagegerrit-maven-stage.yaml).

    This is a documentation-only change; no code or behaviour is affected.

v0.2.1

Bug Fixes

  • Magic repos may not have the same branches that the source repo does make the assumption / requirement that the magic repo uses refs/heads/main for everything

v0.2.0

New Features

  • Required workflows are now searched for out of the ORGANIZATION/.github magic repository which matches with ‘required’ as part of the workflow filename.

Upgrade Notes

  • Only workflow files will be searched for relevant jobs to execute. They must now also contain ‘gerrit’ in the filename.

    ex gerrit-verify.yaml or verify-gerrit.yaml instead of a verify.yaml

  • Workflows must now all contain ‘gerrit’ as part of their filename

  • Workflows must now have the search filter word as part of their filename

  • Workflow names (friendly name inside the workflow) are no longer searched for triggering purposes

v0.1.0

Prelude

This is the initial release of gerrit_to_platform.