You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Implement the read-only planning stage for one manually selected release line using the reusable engine.
The same planner must work from GitHub Actions and the local CLI.
Inputs
branch — required;
ref / commit SHA — optional planning base, not necessarily the final release commit;
version — optional explicit override;
channel — alpha / beta / rc / final;
ignore_open_backport — boolean;
create_follow_up_milestone — boolean/choice where applicable.
If ref is omitted, resolve selected branch HEAD.
If ref is supplied:
resolve it to an immutable SHA;
require it to belong to the selected release line and be an ancestor of/equal to the selected branch HEAD;
use it as the analysis/preparation base;
do not assume it will be the final release SHA if changelog/version files still need a release-preparation commit.
Persist the planning base SHA in ReleasePlan. The final merged release SHA does not exist at this stage and must not be predicted. It is produced later by #73 after the release preparation PR is merged and revalidated.
Consumer discovery contract
Use consumer configuration/adapters to discover:
version source and current app version;
selected branch/ref;
previous relevant release/tag;
merged PRs in the release range;
direct commits not represented by PRs;
translation activity;
dependency activity;
configured changelog strategy/target;
current milestone;
open PRs against selected stable.
Do not hardcode LibreSign file paths in domain logic.
For LibreSign, appinfo/info.xml is the primary version/Nextcloud-compatibility source configured through #83; package mirrors are consistency checks, not independent version authorities.
Previous release / comparison range
Do not use GitHub's repository-wide "latest release" as the previous release. In a multi-stable repository it can belong to another release line.
Determine the previous release from Git ancestry:
list tags matching the consumer-configured tag prefix + supported app version syntax;
resolve tag commits;
keep only tags whose commits are ancestors of/equal to the planning base SHA;
choose the closest reachable release tag in commit history;
if multiple release tags resolve to the same commit, choose the highest valid app version;
use the range previous-tag..planning-base for release-activity discovery.
Ignore unrelated/non-version tags.
If no previous reachable release tag exists, fail unless the consumer config provides an explicit initial-history baseline. Do not silently scan the whole repository history.
Persist previous tag and previous tag SHA in ReleasePlan.
Version proposal
Use merged PR titles as the Conventional Commit classification source.
For an existing release line:
any included feat PR → minor;
otherwise releasable activity → patch.
Direct translation/maintenance commits count as release activity but do not promote to minor.
Major is not inferred from commits. A Conventional Commit ! / BREAKING CHANGE marker is surfaced as a warning requiring maintainer attention, but it does not automatically create a new LibreSign major because major lines are opened explicitly with the Nextcloud/framework release line.
For the first release on a new line, do not invent a major from commit history. Use the configured app base version/release-line metadata. Development/prerelease suffixes such as -dev, alpha, beta or RC are normalized only according to the explicitly selected channel/final transition from #80.
Explicit version override is accepted only after validation against current version, branch/line, channel and existing tags.
The CLI/workflow accepts either 15.0.4 or v15.0.4 when the configured tag prefix is v. Normalize internally to app version 15.0.4 and derive tag v15.0.4; never write the tag prefix into appinfo/info.xml.
Backport blocker
Do not block on a backport request/comment without a PR.
Block only when an actual open backport PR targets the selected stable, unless ignore_open_backport=true.
Detection considers:
PR base branch == selected stable;
backport/stable title/body/metadata conventions;
optional consumer-configured labels.
A repository-wide label:backport-request query is not sufficient.
Other open PRs directly targeting the stable may be surfaced as warnings without becoming hard blockers unless consumer policy says otherwise.
Validation
Fail or warn clearly for:
missing/invalid branch/ref;
ref not valid for selected release line;
inconsistent configured release files;
unexpected existing target tag/release;
missing expected milestone;
invalid version regression;
no releasable activity;
missing configured changelog target/strategy;
stale branch/ref movement.
Translation-only and dependency-only releases are valid.
Output artifact: ReleasePlan v1
This issue's stable handoff artifact is ReleasePlan v1.
It is immutable planning data. Later stages may reference its id/hash but must not mutate it in place.
Produce machine-readable JSON plus human GitHub Step Summary.
The JSON contract is versioned (for example schema: 1) and must be validated by tests so workflows are not coupled to undocumented fields.
Parent: #70
Depends on: #78, #79, #80, #82, #83, #84, #87
Blocks: #72, #74, #76
Goal
Implement the read-only planning stage for one manually selected release line using the reusable engine.
The same planner must work from GitHub Actions and the local CLI.
Inputs
branch— required;ref/ commit SHA — optional planning base, not necessarily the final release commit;version— optional explicit override;channel— alpha / beta / rc / final;ignore_open_backport— boolean;create_follow_up_milestone— boolean/choice where applicable.If
refis omitted, resolve selected branch HEAD.If
refis supplied:Persist the planning base SHA in
ReleasePlan. The final merged release SHA does not exist at this stage and must not be predicted. It is produced later by #73 after the release preparation PR is merged and revalidated.Consumer discovery contract
Use consumer configuration/adapters to discover:
Do not hardcode LibreSign file paths in domain logic.
For LibreSign,
appinfo/info.xmlis the primary version/Nextcloud-compatibility source configured through #83; package mirrors are consistency checks, not independent version authorities.Previous release / comparison range
Do not use GitHub's repository-wide "latest release" as the previous release. In a multi-stable repository it can belong to another release line.
Determine the previous release from Git ancestry:
previous-tag..planning-basefor release-activity discovery.Ignore unrelated/non-version tags.
If no previous reachable release tag exists, fail unless the consumer config provides an explicit initial-history baseline. Do not silently scan the whole repository history.
Persist previous tag and previous tag SHA in
ReleasePlan.Version proposal
Use merged PR titles as the Conventional Commit classification source.
For an existing release line:
featPR → minor;Direct translation/maintenance commits count as release activity but do not promote to minor.
Major is not inferred from commits. A Conventional Commit
!/BREAKING CHANGEmarker is surfaced as a warning requiring maintainer attention, but it does not automatically create a new LibreSign major because major lines are opened explicitly with the Nextcloud/framework release line.Prerelease transitions use #80.
For the first release on a new line, do not invent a major from commit history. Use the configured app base version/release-line metadata. Development/prerelease suffixes such as
-dev, alpha, beta or RC are normalized only according to the explicitly selected channel/final transition from #80.Explicit version override is accepted only after validation against current version, branch/line, channel and existing tags.
The CLI/workflow accepts either
15.0.4orv15.0.4when the configured tag prefix isv. Normalize internally to app version15.0.4and derive tagv15.0.4; never write the tag prefix intoappinfo/info.xml.Backport blocker
Do not block on a backport request/comment without a PR.
Block only when an actual open backport PR targets the selected stable, unless
ignore_open_backport=true.Detection considers:
A repository-wide
label:backport-requestquery is not sufficient.Other open PRs directly targeting the stable may be surfaced as warnings without becoming hard blockers unless consumer policy says otherwise.
Validation
Fail or warn clearly for:
Translation-only and dependency-only releases are valid.
Output artifact: ReleasePlan v1
This issue's stable handoff artifact is
ReleasePlan v1.It is immutable planning data. Later stages may reference its id/hash but must not mutate it in place.
Produce machine-readable JSON plus human GitHub Step Summary.
The JSON contract is versioned (for example
schema: 1) and must be validated by tests so workflows are not coupled to undocumented fields.It contains:
This stage performs no mutation.
Acceptance criteria
featcommit insidefixPR does not cause minor;featPR causes minor;ReleasePlan v1JSON schema/fixture is committed and becomes the input contract for Prepare deterministic reviewable release PRs from a ReleasePlan #72 and the planning input for later stages.Definition of done
LibreCodeCoop/release-tool;ReleasePlan v1schema and representative fixtures are committed;ReleasePlan v1contract without additional design decisions.