Skip to content

ci: add dev-close-notice workflow (trial)#13633

Merged
ilhan007 merged 8 commits into
mainfrom
ci/dev-close-notice
Jun 10, 2026
Merged

ci: add dev-close-notice workflow (trial)#13633
ilhan007 merged 8 commits into
mainfrom
ci/dev-close-notice

Conversation

@ilhan007

@ilhan007 ilhan007 commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

What

During the dev-close window (the days before a release), auto-comment on PRs targeting main that introduce public-API changes, asking contributors to hold the merge until the release ships.

How

On every pull_request event:

  1. Skip unless today falls inside a configured dev-close window (inline list).
  2. Skip unless the PR title is feat: or refactor: (no-PoC/WIP markers).
  3. Build the PR head's Custom Elements Manifest, diff it against @latest on jsDelivr, then filter the diff to entries whose source files the PR actually touches — neutralizes false positives from PRs that branched off before recent merges to main.
  4. If anything remains, post one comment (idempotent via <!-- dev-close-notice --> marker).

Soft-fails throughout — never blocks CI.

Files

  • .github/workflows/pr-dev-close-notice.yaml — workflow + window check
  • .github/actions/pr-dev-close.mjs — detection + comment

Set REPORT_ONLY=list|diff locally to dry-run without commenting.

Trial config

const DEV_CLOSE_PERIODS = [
  { release: "next", devCloseStart: "2026-06-25", releaseDate: "2026-07-06" },
];

Posts a comment on open PRs targeting `main` during the dev-close period
(week before a release) to remind contributors that the PR should not be
merged until the release ships.

Trigger: pull_request events + daily schedule (07:17 UTC) + manual.

Trial run: only the next dev-close window is configured inline:
  2026-06-29 (dev close start) → 2026-07-06 (release date)

If this works as expected we'll extend the schedule (and likely move it
to a JSON file for easier editing).

The workflow is idempotent — it skips PRs that already have the marker
comment, so re-runs won't spam.
@ilhan007 ilhan007 force-pushed the ci/dev-close-notice branch from 053d6b0 to d9b51c0 Compare June 3, 2026 14:41
ilhan007 and others added 7 commits June 3, 2026 17:51
The previous version flagged PRs purely from their Conventional Commit
title (`feat:` / `feat(...)` / any type with `!`). That misses the
common case in this repo: an additive public-API change committed under
a `fix:` or `refactor:` title.

Now the workflow has two layers:

1. **CEM diff (preferred).** On pull_request events that touched
   `packages/*/src/**`, build `custom-elements-internal.json` on PR
   base AND PR head and diff for public-API additions, removals and type
   changes. Diff logic lives in:
     - `.github/scripts/dev-close/diff-cem.mjs`
       Walks both manifests, filters by `_ui5privacy === 'public'` (or
       `privacy === 'public'`), emits a structured JSON diff.
     - `.github/scripts/dev-close/format-diff.mjs`
       Turns the JSON diff into a Markdown bullet list for the comment.
   We diff the *internal* manifest (not the post-processed public one)
   so we control the privacy filter ourselves rather than depending on
   the build's `processPublicAPI` stripper.

2. **Title regex (fallback).** When CEM diff couldn't run — daily sweep,
   no src changes, or the build failed — the workflow falls back to the
   title regex from the previous version.

Soft-fails throughout: a failed install/generate on either side just
means the diff step reports `status=failed` and the notify job falls
back to the title regex. The workflow itself never fails.

Behavior matrix:
  pull_request + src changed + cem ok          → CEM diff (lists changes)
  pull_request + src changed + cem 'no-changes' → no comment
  pull_request + src changed + cem failed       → title regex
  pull_request + no src changes                 → title regex
  schedule / workflow_dispatch                  → title regex
Per review: a single detection path (CEM diff) is clearer than two layers.
The title regex fallback is removed — if CEM can't run (no src changes
or build fails), the workflow exits without commenting.

Also drops the daily schedule trigger: that path was title-only because
building CEM for every open PR every day is too expensive, and removing
the title regex makes the schedule pointless.

Diff script (diff-cem.mjs) gains coverage borrowed from
nnaydenow/version-compare's per-category logic, kept inside our flat-Map
technique:
  - properties (kind=field) and methods (kind=method) tracked separately
  - events: bubbles, cancelable, parameter add/remove/type changes
  - enums: enum-member adds/removals
  - interfaces: add/remove/deprecation transitions
  - cssStates (in addition to cssParts/cssProperties)
  - deprecation transitions on any tracked entity (newly deprecated,
    un-deprecated, or message changed)

Triggers: pull_request only (opened/reopened/ready_for_review/sync).
Replaces the previous design (workflow + composite action + diff script
+ format script, four files) with two files:
  .github/workflows/pr-dev-close-notice.yaml
  .github/actions/pr-dev-close.mjs

Key simplification: diff PR head vs latest npm (jsdelivr) instead of
building both base AND head in CI. The published custom-elements.json
is already public-only, so we drop the privacy filter too. Saves ~2min
per PR and removes the matrix / fan-out machinery.

Triggers:
  * schedule (07:17 UTC daily) — sweeps all open non-draft PRs
  * pull_request — single-PR path, closes the up-to-24h gap during
    the window
  * workflow_dispatch — manual

Both paths gated by the window-check job; outside the period every run
exits in ~10s with no checkout / install.

Title allowlist (feat / fix / refactor) skips ci/docs/test/chore PRs
before the build, so most runs cost nothing even inside the window.

Comment is friendly, links to the release schedule, and asks the author
to request review from members of @UI5/ui5-team-webc if the change must
ship in the current release.

Trial window: 2026-06-25 → 2026-07-06.
Filter changes (per local report against current open PRs):
  * Drop `fix:` from the title allowlist — fix PRs in this repo overwhelmingly
    change implementation, not surface, so they're noise. Now feat / refactor
    only. A fix that does change public API will slip through; rare enough
    that the noise reduction wins for the trial.
  * Skip titles containing PoC / WIP / DO NOT MERGE markers (case-insensitive,
    with or without brackets) — those PRs aren't merge-bound during dev close.

Result on a current snapshot: 31 open PRs → 22 candidates (with fix) → 8
candidates (without fix or PoC/WIP). The 8 are all feat: PRs.

Local validation harness — REPORT_ONLY env, no GitHub side-effects:
  * REPORT_ONLY=list (or =1) — fast: candidate table only, no builds.
  * REPORT_ONLY=diff [LIMIT=N] — full pipeline, prints would-be comment to
    stdout instead of posting. Stashes a dirty tree on entry, pops on exit
    so the script can iterate without blocking on local edits.
  * RELEASE / RELEASE_DATE become optional in REPORT_ONLY (defaults: "next"
    / "(unset)"). GH_TOKEN + GITHUB_REPO still required.

Tone: the comment is now "heads-up"-flavored, links to the release
schedule (issues/10568), and asks the author to request review from one
or two members of @UI5/ui5-team-webc if the change must ship in the
current release. Comment-only — no auto-block.

Trial window: 2026-06-25 → 2026-07-06.
The dev-close script's local CEM was a leftover `dist/custom-elements.json`
from whatever `yarn build` last ran in the working tree — `yarn generate`
only rebuilds in-source assets (templates, CSS, i18n), not the manifest.
Diffing a stale local CEM against jsdelivr @latest produced the same
phantom diff (e.g. "HeroBanner removed") for every PR.

Three changes in one commit:

1. Rebuild the per-package CEM with `yarn workspace <pkg> generateCEM`
   after `yarn generate`. Each `generateCEM` is fast (~5s) and uses the
   already-installed analyzer.

2. Filter the per-PR diff by the PR's changed source files. CEM entries
   are kept only if their `module.path` maps to a `packages/*/src/` file
   that the PR actually touches. This neutralizes the "old PR vs newer
   main" false positive that surfaces whenever a PR predates a merge to
   main.

3. Suppress published-vs-local artifacts in `fieldDiff`. The published
   CEM is post-processed (`processPublicAPI` strips `_ui5*`); the local
   one keeps them. Compare `_ui5Bubbles` / `_ui5Cancelable` /
   `_ui5parameters` only when the BASE side has them, and fall back to
   `_ui5type` only when both sides do. Without these guards every event
   and every typed slot looked "changed."

Verified locally with `REPORT_ONLY=diff` against all 8 in-scope feat:
PRs against main today — clean per-PR signal, no phantom HeroBanner
removals.
The trial-run detection (CEM diff filtered by changed files) will miss
or mis-attribute things. Adding a short prompt asking contributors to
reply when they believe the comment is a false positive — those replies
are how we tune the heuristic during the pre-release window.
@ilhan007 ilhan007 merged commit 741d9c4 into main Jun 10, 2026
19 of 20 checks passed
@ilhan007 ilhan007 deleted the ci/dev-close-notice branch June 10, 2026 07:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant