From f3c16f894bc4986881dffbcc2987b3aaf87b2409 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Wed, 14 Oct 2026 13:33:40 +0300 Subject: [PATCH 1/3] Mark fully deployed services and move Release into a tabbed side column --- README.md | 8 ++-- release_scope/_static/index.html | 63 ++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 9941565..e759bb0 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,8 @@ as one line: what production runs, the picked tag, how many merge requests or co failed jobs of the picked tag, or of the newest tag before a pick, with the ones allowed to fail counted apart, a mark when the range was cut at `RELEASE_SCOPE_MAX_COMMITS`, and how many rows have no tag yet, with a `+` when the cut range holds no tag, so more untagged rows may lie below it. The failed jobs are those of the tag's pipeline and of -the main pipeline of its commit; failures in other rows show only when the line is opened. +the main pipeline of its commit; failures in other rows show only when the line is opened. A service whose +production runs the head of the default branch, with no rows left to ship, is marked green as fully deployed. Opening a line shows the service's environments with when each was deployed, warnings, a link to create the next tag on the head when rows have no tag yet, merge requests that are not merged yet, and its rows with tags and their pipelines, merge requests or commits with when they were merged or committed, Jira keys with their status, @@ -144,8 +145,9 @@ them. An address with picks replaces the release tags of a `--jira` report; pick a tag that a later run no longer lists, are skipped with a warning. Clearing every pick empties the address, so a reload starts from the release tags again. -**Release** at the bottom turns the picked tags into three lists and a release post, each with a copy button and a -text box to copy from by hand, since browsers allow the copy button only over HTTPS: +**Release**, in a column next to the services that stays in view while they scroll, or below them on a narrow screen, +turns the picked tags into three lists and a release post. Each has a tab of its own, with a copy button and a text box +to copy from by hand, since browsers allow the copy button only over HTTPS: - **Jira tasks**: the keys of every in-scope row from each picked tag down to production, without duplicates, with summary and a status badge: grey to do, blue in progress, green done. Copy them one per line or as a JQL diff --git a/release_scope/_static/index.html b/release_scope/_static/index.html index dfd7bcb..b874b2b 100644 --- a/release_scope/_static/index.html +++ b/release_scope/_static/index.html @@ -33,10 +33,9 @@ [x-cloak] { display: none !important; } * { box-sizing: border-box; } body { margin: 0; background: var(--bg); color: var(--fg); font: 14px/1.5 system-ui, sans-serif; } - main { max-width: 1200px; margin: 0 auto; padding: 16px; } + main { max-width: 1680px; margin: 0 auto; padding: 16px; } h1 { font-size: 24px; margin: 0 0 4px; } h2 { font-size: 18px; margin: 32px 0 8px; border-bottom: 1px solid var(--border); padding-bottom: 4px; } - h3 { font-size: 15px; margin: 0 0 8px; } a { color: var(--accent); text-decoration: none; } a:hover { text-decoration: underline; } code { font: 12px ui-monospace, monospace; } @@ -57,9 +56,15 @@ .warn { color: var(--warn); } .message { white-space: pre-line; } .scroll { overflow-x: auto; } - .outputs { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 12px; margin-top: 16px; } - .outputs .wide { grid-column: 1 / -1; } - .out-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; } + .layout { display: grid; grid-template-columns: minmax(0, 1fr) 420px; gap: 24px; align-items: start; } + .layout > aside { position: sticky; top: 0; max-height: 100vh; overflow-y: auto; padding: 0 4px 16px; } + @media (max-width: 1000px) { + .layout { display: block; } + .layout > aside { position: static; max-height: none; } + } + .tabs { display: flex; flex-wrap: wrap; gap: 4px; margin: 8px 0; } + .outputs textarea { min-height: 160px; } + .out-head { display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap; } tr.out-of-scope td { opacity: 0.55; } tr.shipped td { background: color-mix(in srgb, var(--accent) 12%, transparent); } .tag { white-space: nowrap; } @@ -67,6 +72,8 @@ .service > summary { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; padding: 8px 12px; cursor: pointer; list-style: none; } .service[open] > summary { border-bottom: 1px solid var(--border); } + .service.deployed { border-left: 4px solid var(--good); background: color-mix(in srgb, var(--good) 6%, transparent); } + .service.deployed .name { color: var(--good); } .service > summary::before { content: "▸"; color: var(--muted); } .service[open] > summary::before { content: "▾"; } .service .name { min-width: 200px; font-weight: 600; } @@ -119,11 +126,13 @@

+
+

+
+