Skip to content

Define the reusable release engine architecture and stage contracts #78

Description

@vitormattos

Parent: #70
Blocks: #82, #71, #79, #80

Goal

Define the production architecture for the reusable release system before implementing release behavior.

LibreSign is the first consumer, but the core implementation lives outside LibreSign/libresign.

LibreSign/libresign#8447 is a disposable proof of concept and is not a production dependency.

Repository boundary

LibreCodeCoop/release-tool owns the production PHP release engine / PHAR, domain policies, adapters, configuration schema and engine tests.

LibreCodeCoop/github-workflows owns the reusable GitHub Actions/workflow orchestration that downloads/verifies/invokes a pinned PHAR release.

The engine and orchestration are separate repositories by design.

Consumer-specific configuration/adapters define repository/version mapping, stable-branch naming, changelog storage strategy, release-file allowlist, milestone naming and packaging commands.

Consumer repositories own only:

  • configuration;
  • branch/version mapping;
  • release-file mapping;
  • changelog storage strategy selection;
  • packaging integration.

Implementation stack and distribution

The production release engine is a PHP 8.3+ CLI distributed as a PHAR.

The same executable/domain implementation must run locally and in GitHub Actions. Do not maintain a parallel Python release engine.

The full PHP toolchain, PHAR, CI and CLI quality contract is #82.

Existing Python release-lifecycle code/actions in github-workflows are prototypes/current transitional tooling only. Release-specific behavior is migrated to the PHP tool under #82. Unrelated catalog/governance Python tooling remains Python.

The release engine is developed in the dedicated LibreCodeCoop/release-tool repository so github-workflows remains focused on orchestration/catalog distribution. Workflows consume a pinned PHAR/CLI release; consumer apps configure it.

A suitable internal shape is conceptually:

src/
├── Domain/
├── Application/
└── Infrastructure/

bin/
└── release-tool

The exact class/module names may vary, but these layer boundaries are mandatory.

Architecture

GitHub Actions
    ↓
Application use cases / CLI
    ↓
Release domain policies
    ↓
Git / GitHub / filesystem adapters

GitHub Actions

Workflow YAML is orchestration only.

It may:

  • checkout repositories;
  • configure runtimes;
  • call the CLI;
  • pass explicit inputs/outputs;
  • publish summaries/artifacts;
  • enforce permissions/environments.

It must not contain substantial release policy.

Application layer

Expose explicit use cases such as:

  • plan release;
  • prepare changelog/release PR;
  • synchronize stable release state;
  • rotate milestone;
  • prepare GitHub Release draft;
  • verify publication.

Domain

Expected deterministic concepts include:

  • Version;
  • ReleaseChannel;
  • ReleaseActivity;
  • ReleasePlan;
  • VersionPolicy;
  • ChangelogPolicy;
  • BackportPolicy;
  • MilestonePolicy.

Domain code must not invoke git, gh, GitHub Actions APIs or mutate files.

Infrastructure

Adapters own external I/O:

  • Git history;
  • GitHub API;
  • files;
  • commands.

Consumer-specific filesystem paths must be configuration/adapter data, not hardcoded core policy.

ReleaseActivity

Normalize release inputs before version/changelog decisions.

At minimum:

  • merged PRs in release range;
  • direct commits not represented by PRs;
  • translation activity;
  • dependency activity;
  • labels/context;
  • source branch/ref provenance.

Then consume it independently:

ReleaseActivity
   ├── VersionPolicy
   └── ChangelogPolicy

ReleasePlan

Before mutation generate a machine-readable immutable plan containing at least:

  • repository/consumer id;
  • selected branch;
  • resolved immutable SHA;
  • previous relevant release/tag;
  • proposed version;
  • explicit version override, if any;
  • channel;
  • bump reason;
  • release activity;
  • changelog target/strategy;
  • milestone;
  • follow-up milestone choice;
  • matching open backport PRs;
  • blocker override state;
  • warnings/readiness.

Every mutating stage revalidates current state against the plan.

CLI

The same engine powers workflows and local usage.

Required capabilities:

  • read-only plan;
  • machine-readable JSON output;
  • human-readable summary;
  • deterministic dry-run for mutations;
  • explicit apply commands for supported stages;
  • non-zero exit on contract violations.

The normal maintainer workflow remains GitHub Actions; local CLI is for diagnostics/manual recovery.

Consumer configuration

The engine must support consumer configuration for at least:

  • stable branch naming/mapping;
  • version source files;
  • changelog storage strategy;
  • allowed release files;
  • milestone naming;
  • packaging command/verification hooks.

Do not hardcode LibreSign paths in reusable domain code.

Workflow boundaries

Keep external stages coarse:

  1. plan;
  2. prepare release PR(s);
  3. milestone transition;
  4. release draft;
  5. publication verification.

Do not create one workflow per small policy rule.

Idempotency and safety

  • planning is read-only;
  • every mutation supports dry-run/plan output;
  • reruns either converge safely or stop with precise diagnostics;
  • stale branch/ref state stops mutation;
  • privileged GitHub mutations are separated from read-only analysis.

Acceptance criteria

Definition of done

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions