Skip to content

check-upstream-version-task: structured multi-key JSON state - #169

Merged
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state
Jun 21, 2026
Merged

check-upstream-version-task: structured multi-key JSON state#169
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Closes#168.

Raised by ptr727/ESPHome-NonRoot while re-syncing from #167: the canonical check-upstream-version-task.yml serialized only a single bare-string version, so a wrapper pinning several upstream components (ESPHome-NonRoot pins both esphome and the device-builder) could not converge on it and kept a bespoke tracker.

Change

  • Structured state file. The resolver now prints a JSON object of name -> version; the task normalizes it (sorted keys, pretty) and writes it as the canonical state file. One key for the common single-version case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the build by key. This also makes the upstream-version.json extension honest.
  • Changed-key summary. The bump PR title/body are diffed against the prior state and name only the keys that actually moved. The trivial single-version case still renders Update upstream version to X; multi-key renders Update upstream versions: esphome to 2026.7.0 plus a per-component body list.
  • Robustness. Missing/corrupt state diffs cleanly against an empty object (first run works); a resolver that prints non-object output fails with a clear contract message; an unchanged object yields no diff so create-pull-request opens nothing.
  • Docs.AGENTS.md wrapper-repo description updated to the JSON name -> version contract.
  • Workspace. Swapped gruntfuggly.todo-tree for fanaticpythoner.better-todo-tree in DotNet.code-workspace (bundled per request).

The merge-bot keys only on branch refs (upstream-version-<base>), so it needs no change.

Validation

Ran the resolve/compose logic locally across single-key first-run, multi-key first-run, partial move (one of two changed), no-change (empty diff → no PR), and malformed output (rejected). YAML validated.

🤖 Generated with Claude Code

The canonical upstream-version tracker serialized only a single bare string
(resolver printed one line; state file written raw), so a wrapper pinning more
than one upstream component could not converge on it and kept a bespoke tracker.
Make the resolver print a JSON object of name -> version and write it as the
canonical (sorted, pretty) state file: one key for the common single-version
case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the
build by key. This also makes the upstream-version.json extension honest. The
bump PR title/body now name only the keys that actually moved, diffed against
the prior state. Update the AGENTS.md wrapper-repo description to match.
Also swap the todo-tree workspace extension for fanaticpythoner.better-todo-tree.
Closes#168
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CopilotAI review requested due to automatic review settings June 21, 2026 20:12

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the upstream-version tracking reusable workflow to support wrapper repos that need to pin multiple upstream components by moving from a single string state to a structured JSON object, and aligns documentation/workspace defaults with that new contract.

Changes:

  • Switch .github/workflows/check-upstream-version-task.yml to accept resolver output as a JSON object (name -> version), normalize it, and generate PR title/body from per-key diffs.
  • Document the new multi-key JSON state contract in AGENTS.md.
  • Update DotNet.code-workspace extension recommendations (swap TODO-tree extension).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

FileDescription
DotNet.code-workspaceReplaces the TODO tree extension recommendation.
AGENTS.mdUpdates wrapper-repo guidance to the new JSON name -> version state contract.
.github/workflows/check-upstream-version-task.ymlImplements structured JSON state parsing/normalization and changed-key PR title/body composition.

Comment thread.github/workflows/check-upstream-version-task.yml
Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Require the resolver object to be non-empty with all-string values so malformed
output fails fast instead of committing state the build cannot consume. Diff
across the union of old+new keys so a removed key is reported (carries null);
title a key-less reserialization as a canonicalize-only change rather than an
empty "Update upstream versions: ".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
A state file that was valid JSON but not an object (string/array/number) passed
the existing-file guard and then broke the `$old + $new` union diff. Accept the
prior state only when it parses as an object; otherwise diff against `{}`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Comment thread.github/workflows/check-upstream-version-task.yml
A version string carrying an embedded newline would corrupt the single-line
title=/body GITHUB_OUTPUT, so require keys and values to be single-line. Also
correct the state-write comment: a differently-formatted-but-identical prior
file does change and opens a canonicalize-only PR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit 7566c39 into developJun 21, 2026
9 checks passed
@ptr727
ptr727 deleted the upstream-version-multikey-state branch June 21, 2026 20:33
ptr727 added a commit to ptr727/ESPHome-NonRoot that referenced this pull request Jun 21, 2026
* Adopt canonical upstream-version tracker for multi-key state
Replace the bespoke check-esphome-version.yml with the carried
check-upstream-version-task.yml plus a thin scheduled entry-point
(check-upstream-version.yml) whose resolver prints the esphome and
device-builder versions as a JSON object. Rename the state file
esphome-version.json -> upstream-version.json (keyed esphome and
device_builder, sorted JSON) and point build-docker-task.yml, the
merge-bot refs (upstream-version-<base>), and the PR paths-filter at it.
Converges on ptr727/ProjectTemplate#169, which added structured
multi-key state to the canonical task per the gap filed in #168.
Closes#66.
* Write upstream-version state file as CRLF per template fix
Re-sync the carried check-upstream-version-task.yml to write the state
file as CRLF (jq emits LF), honoring .editorconfig's .json rule, and
convert upstream-version.json to CRLF to match. Converges on
ptr727/ProjectTemplate#172, which resolved the LF-vs-CRLF state-file
nuance filed in #170.
* Harden upstream resolver curl error reporting
Add --show-error/--location to the PyPI curl calls and emit ::error::
annotations on resolve failure, so a failed scheduled run surfaces a
clear cause. Addresses Copilot review feedback on PR #67.
* Use product names in resolver errors and tracker wording
Reference ESPHome and esphome-device-builder (the PyPI/product names) in
the resolve-failure messages, and update the remaining "ESPHome-version
bump" mention in AGENTS.md to "upstream-version bump". Addresses Copilot
review feedback on PR #67.
ptr727 added a commit that referenced this pull request Jun 22, 2026
… quota (#180)
Promote accumulated `develop` work to `main` so derived repos can
re-sync from `main` (the stable ref) rather than tracking `develop`.
Docs / CI / config only — no `version.json` bump (no functional change).
## Notable contents
- **Consolidate code style + carry contract** (#178, closes#175): one
root `CODESTYLE.md` (General → .NET → Python, droppable sections);
`PyPiLibrary/CODESTYLE.md` removed; `CODESTYLE.md` +
`.vscode/tasks.json` added to the verbatim-carry list; official-tooling
casing (`.Net*` → `.NET*`); clean-compile rule; brownfield/suppression
scope hierarchy; `dependsOrder: sequence` on the `.NET Format` task.
- **Clarify project-rule home + harden Copilot runbook** (#173): project
conventions/API contracts live in `AGENTS.md`, not
`.github/copilot-instructions.md`; a no-inline-comment review is a clean
pass; poll for the auto-review before self-triggering.
- **Cut Actions artifact-storage quota usage** (#179): PR smoke builds
no longer upload artifacts nothing consumes.
- Plus prior develop work: docs/comment cleanup (#167),
`check-upstream-version-task` structured multi-key state (#169) + CRLF
state file (#172), `publish-docker-readme-task`, and routine codegen
updates.
## Notes
- develop → main is **merge-commit only** (preserves develop's commit
list as a second-parent reference on `main`).
- Merging closes#173 and #175 (their `Closes` keywords reach the
default branch).
- After merge, the downstream re-sync issues (each updated with the
current state) can point at `main`.
Sign up for freeto 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.

2 participants

@ptr727
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
check-upstream-version-task: structured multi-key JSON state by ptr727 · Pull Request #169 · ptr727/ProjectTemplate · GitHub
Skip to content

check-upstream-version-task: structured multi-key JSON state - #169

Merged
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state
Jun 21, 2026
Merged

check-upstream-version-task: structured multi-key JSON state#169
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Closes#168.

Raised by ptr727/ESPHome-NonRoot while re-syncing from #167: the canonical check-upstream-version-task.yml serialized only a single bare-string version, so a wrapper pinning several upstream components (ESPHome-NonRoot pins both esphome and the device-builder) could not converge on it and kept a bespoke tracker.

Change

  • Structured state file. The resolver now prints a JSON object of name -> version; the task normalizes it (sorted keys, pretty) and writes it as the canonical state file. One key for the common single-version case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the build by key. This also makes the upstream-version.json extension honest.
  • Changed-key summary. The bump PR title/body are diffed against the prior state and name only the keys that actually moved. The trivial single-version case still renders Update upstream version to X; multi-key renders Update upstream versions: esphome to 2026.7.0 plus a per-component body list.
  • Robustness. Missing/corrupt state diffs cleanly against an empty object (first run works); a resolver that prints non-object output fails with a clear contract message; an unchanged object yields no diff so create-pull-request opens nothing.
  • Docs.AGENTS.md wrapper-repo description updated to the JSON name -> version contract.
  • Workspace. Swapped gruntfuggly.todo-tree for fanaticpythoner.better-todo-tree in DotNet.code-workspace (bundled per request).

The merge-bot keys only on branch refs (upstream-version-<base>), so it needs no change.

Validation

Ran the resolve/compose logic locally across single-key first-run, multi-key first-run, partial move (one of two changed), no-change (empty diff → no PR), and malformed output (rejected). YAML validated.

🤖 Generated with Claude Code

The canonical upstream-version tracker serialized only a single bare string
(resolver printed one line; state file written raw), so a wrapper pinning more
than one upstream component could not converge on it and kept a bespoke tracker.
Make the resolver print a JSON object of name -> version and write it as the
canonical (sorted, pretty) state file: one key for the common single-version
case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the
build by key. This also makes the upstream-version.json extension honest. The
bump PR title/body now name only the keys that actually moved, diffed against
the prior state. Update the AGENTS.md wrapper-repo description to match.
Also swap the todo-tree workspace extension for fanaticpythoner.better-todo-tree.
Closes#168
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CopilotAI review requested due to automatic review settings June 21, 2026 20:12

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the upstream-version tracking reusable workflow to support wrapper repos that need to pin multiple upstream components by moving from a single string state to a structured JSON object, and aligns documentation/workspace defaults with that new contract.

Changes:

  • Switch .github/workflows/check-upstream-version-task.yml to accept resolver output as a JSON object (name -> version), normalize it, and generate PR title/body from per-key diffs.
  • Document the new multi-key JSON state contract in AGENTS.md.
  • Update DotNet.code-workspace extension recommendations (swap TODO-tree extension).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

FileDescription
DotNet.code-workspaceReplaces the TODO tree extension recommendation.
AGENTS.mdUpdates wrapper-repo guidance to the new JSON name -> version state contract.
.github/workflows/check-upstream-version-task.ymlImplements structured JSON state parsing/normalization and changed-key PR title/body composition.

Comment thread.github/workflows/check-upstream-version-task.yml
Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Require the resolver object to be non-empty with all-string values so malformed
output fails fast instead of committing state the build cannot consume. Diff
across the union of old+new keys so a removed key is reported (carries null);
title a key-less reserialization as a canonicalize-only change rather than an
empty "Update upstream versions: ".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
A state file that was valid JSON but not an object (string/array/number) passed
the existing-file guard and then broke the `$old + $new` union diff. Accept the
prior state only when it parses as an object; otherwise diff against `{}`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Comment thread.github/workflows/check-upstream-version-task.yml
A version string carrying an embedded newline would corrupt the single-line
title=/body GITHUB_OUTPUT, so require keys and values to be single-line. Also
correct the state-write comment: a differently-formatted-but-identical prior
file does change and opens a canonicalize-only PR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit 7566c39 into developJun 21, 2026
9 checks passed
@ptr727
ptr727 deleted the upstream-version-multikey-state branch June 21, 2026 20:33
ptr727 added a commit to ptr727/ESPHome-NonRoot that referenced this pull request Jun 21, 2026
* Adopt canonical upstream-version tracker for multi-key state
Replace the bespoke check-esphome-version.yml with the carried
check-upstream-version-task.yml plus a thin scheduled entry-point
(check-upstream-version.yml) whose resolver prints the esphome and
device-builder versions as a JSON object. Rename the state file
esphome-version.json -> upstream-version.json (keyed esphome and
device_builder, sorted JSON) and point build-docker-task.yml, the
merge-bot refs (upstream-version-<base>), and the PR paths-filter at it.
Converges on ptr727/ProjectTemplate#169, which added structured
multi-key state to the canonical task per the gap filed in #168.
Closes#66.
* Write upstream-version state file as CRLF per template fix
Re-sync the carried check-upstream-version-task.yml to write the state
file as CRLF (jq emits LF), honoring .editorconfig's .json rule, and
convert upstream-version.json to CRLF to match. Converges on
ptr727/ProjectTemplate#172, which resolved the LF-vs-CRLF state-file
nuance filed in #170.
* Harden upstream resolver curl error reporting
Add --show-error/--location to the PyPI curl calls and emit ::error::
annotations on resolve failure, so a failed scheduled run surfaces a
clear cause. Addresses Copilot review feedback on PR #67.
* Use product names in resolver errors and tracker wording
Reference ESPHome and esphome-device-builder (the PyPI/product names) in
the resolve-failure messages, and update the remaining "ESPHome-version
bump" mention in AGENTS.md to "upstream-version bump". Addresses Copilot
review feedback on PR #67.
ptr727 added a commit that referenced this pull request Jun 22, 2026
… quota (#180)
Promote accumulated `develop` work to `main` so derived repos can
re-sync from `main` (the stable ref) rather than tracking `develop`.
Docs / CI / config only — no `version.json` bump (no functional change).
## Notable contents
- **Consolidate code style + carry contract** (#178, closes#175): one
root `CODESTYLE.md` (General → .NET → Python, droppable sections);
`PyPiLibrary/CODESTYLE.md` removed; `CODESTYLE.md` +
`.vscode/tasks.json` added to the verbatim-carry list; official-tooling
casing (`.Net*` → `.NET*`); clean-compile rule; brownfield/suppression
scope hierarchy; `dependsOrder: sequence` on the `.NET Format` task.
- **Clarify project-rule home + harden Copilot runbook** (#173): project
conventions/API contracts live in `AGENTS.md`, not
`.github/copilot-instructions.md`; a no-inline-comment review is a clean
pass; poll for the auto-review before self-triggering.
- **Cut Actions artifact-storage quota usage** (#179): PR smoke builds
no longer upload artifacts nothing consumes.
- Plus prior develop work: docs/comment cleanup (#167),
`check-upstream-version-task` structured multi-key state (#169) + CRLF
state file (#172), `publish-docker-readme-task`, and routine codegen
updates.
## Notes
- develop → main is **merge-commit only** (preserves develop's commit
list as a second-parent reference on `main`).
- Merging closes#173 and #175 (their `Closes` keywords reach the
default branch).
- After merge, the downstream re-sync issues (each updated with the
current state) can point at `main`.
Sign up for freeto 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.

2 participants

@ptr727
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' check-upstream-version-task: structured multi-key JSON state by ptr727 · Pull Request #169 · ptr727/ProjectTemplate · GitHub
Skip to content

check-upstream-version-task: structured multi-key JSON state - #169

Merged
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state
Jun 21, 2026
Merged

check-upstream-version-task: structured multi-key JSON state#169
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Closes#168.

Raised by ptr727/ESPHome-NonRoot while re-syncing from #167: the canonical check-upstream-version-task.yml serialized only a single bare-string version, so a wrapper pinning several upstream components (ESPHome-NonRoot pins both esphome and the device-builder) could not converge on it and kept a bespoke tracker.

Change

  • Structured state file. The resolver now prints a JSON object of name -> version; the task normalizes it (sorted keys, pretty) and writes it as the canonical state file. One key for the common single-version case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the build by key. This also makes the upstream-version.json extension honest.
  • Changed-key summary. The bump PR title/body are diffed against the prior state and name only the keys that actually moved. The trivial single-version case still renders Update upstream version to X; multi-key renders Update upstream versions: esphome to 2026.7.0 plus a per-component body list.
  • Robustness. Missing/corrupt state diffs cleanly against an empty object (first run works); a resolver that prints non-object output fails with a clear contract message; an unchanged object yields no diff so create-pull-request opens nothing.
  • Docs.AGENTS.md wrapper-repo description updated to the JSON name -> version contract.
  • Workspace. Swapped gruntfuggly.todo-tree for fanaticpythoner.better-todo-tree in DotNet.code-workspace (bundled per request).

The merge-bot keys only on branch refs (upstream-version-<base>), so it needs no change.

Validation

Ran the resolve/compose logic locally across single-key first-run, multi-key first-run, partial move (one of two changed), no-change (empty diff → no PR), and malformed output (rejected). YAML validated.

🤖 Generated with Claude Code

The canonical upstream-version tracker serialized only a single bare string
(resolver printed one line; state file written raw), so a wrapper pinning more
than one upstream component could not converge on it and kept a bespoke tracker.
Make the resolver print a JSON object of name -> version and write it as the
canonical (sorted, pretty) state file: one key for the common single-version
case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the
build by key. This also makes the upstream-version.json extension honest. The
bump PR title/body now name only the keys that actually moved, diffed against
the prior state. Update the AGENTS.md wrapper-repo description to match.
Also swap the todo-tree workspace extension for fanaticpythoner.better-todo-tree.
Closes#168
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CopilotAI review requested due to automatic review settings June 21, 2026 20:12

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the upstream-version tracking reusable workflow to support wrapper repos that need to pin multiple upstream components by moving from a single string state to a structured JSON object, and aligns documentation/workspace defaults with that new contract.

Changes:

  • Switch .github/workflows/check-upstream-version-task.yml to accept resolver output as a JSON object (name -> version), normalize it, and generate PR title/body from per-key diffs.
  • Document the new multi-key JSON state contract in AGENTS.md.
  • Update DotNet.code-workspace extension recommendations (swap TODO-tree extension).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

FileDescription
DotNet.code-workspaceReplaces the TODO tree extension recommendation.
AGENTS.mdUpdates wrapper-repo guidance to the new JSON name -> version state contract.
.github/workflows/check-upstream-version-task.ymlImplements structured JSON state parsing/normalization and changed-key PR title/body composition.

Comment thread.github/workflows/check-upstream-version-task.yml
Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Require the resolver object to be non-empty with all-string values so malformed
output fails fast instead of committing state the build cannot consume. Diff
across the union of old+new keys so a removed key is reported (carries null);
title a key-less reserialization as a canonicalize-only change rather than an
empty "Update upstream versions: ".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
A state file that was valid JSON but not an object (string/array/number) passed
the existing-file guard and then broke the `$old + $new` union diff. Accept the
prior state only when it parses as an object; otherwise diff against `{}`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Comment thread.github/workflows/check-upstream-version-task.yml
A version string carrying an embedded newline would corrupt the single-line
title=/body GITHUB_OUTPUT, so require keys and values to be single-line. Also
correct the state-write comment: a differently-formatted-but-identical prior
file does change and opens a canonicalize-only PR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit 7566c39 into developJun 21, 2026
9 checks passed
@ptr727
ptr727 deleted the upstream-version-multikey-state branch June 21, 2026 20:33
ptr727 added a commit to ptr727/ESPHome-NonRoot that referenced this pull request Jun 21, 2026
* Adopt canonical upstream-version tracker for multi-key state
Replace the bespoke check-esphome-version.yml with the carried
check-upstream-version-task.yml plus a thin scheduled entry-point
(check-upstream-version.yml) whose resolver prints the esphome and
device-builder versions as a JSON object. Rename the state file
esphome-version.json -> upstream-version.json (keyed esphome and
device_builder, sorted JSON) and point build-docker-task.yml, the
merge-bot refs (upstream-version-<base>), and the PR paths-filter at it.
Converges on ptr727/ProjectTemplate#169, which added structured
multi-key state to the canonical task per the gap filed in #168.
Closes#66.
* Write upstream-version state file as CRLF per template fix
Re-sync the carried check-upstream-version-task.yml to write the state
file as CRLF (jq emits LF), honoring .editorconfig's .json rule, and
convert upstream-version.json to CRLF to match. Converges on
ptr727/ProjectTemplate#172, which resolved the LF-vs-CRLF state-file
nuance filed in #170.
* Harden upstream resolver curl error reporting
Add --show-error/--location to the PyPI curl calls and emit ::error::
annotations on resolve failure, so a failed scheduled run surfaces a
clear cause. Addresses Copilot review feedback on PR #67.
* Use product names in resolver errors and tracker wording
Reference ESPHome and esphome-device-builder (the PyPI/product names) in
the resolve-failure messages, and update the remaining "ESPHome-version
bump" mention in AGENTS.md to "upstream-version bump". Addresses Copilot
review feedback on PR #67.
ptr727 added a commit that referenced this pull request Jun 22, 2026
… quota (#180)
Promote accumulated `develop` work to `main` so derived repos can
re-sync from `main` (the stable ref) rather than tracking `develop`.
Docs / CI / config only — no `version.json` bump (no functional change).
## Notable contents
- **Consolidate code style + carry contract** (#178, closes#175): one
root `CODESTYLE.md` (General → .NET → Python, droppable sections);
`PyPiLibrary/CODESTYLE.md` removed; `CODESTYLE.md` +
`.vscode/tasks.json` added to the verbatim-carry list; official-tooling
casing (`.Net*` → `.NET*`); clean-compile rule; brownfield/suppression
scope hierarchy; `dependsOrder: sequence` on the `.NET Format` task.
- **Clarify project-rule home + harden Copilot runbook** (#173): project
conventions/API contracts live in `AGENTS.md`, not
`.github/copilot-instructions.md`; a no-inline-comment review is a clean
pass; poll for the auto-review before self-triggering.
- **Cut Actions artifact-storage quota usage** (#179): PR smoke builds
no longer upload artifacts nothing consumes.
- Plus prior develop work: docs/comment cleanup (#167),
`check-upstream-version-task` structured multi-key state (#169) + CRLF
state file (#172), `publish-docker-readme-task`, and routine codegen
updates.
## Notes
- develop → main is **merge-commit only** (preserves develop's commit
list as a second-parent reference on `main`).
- Merging closes#173 and #175 (their `Closes` keywords reach the
default branch).
- After merge, the downstream re-sync issues (each updated with the
current state) can point at `main`.
Sign up for freeto 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.

2 participants

@ptr727
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' check-upstream-version-task: structured multi-key JSON state by ptr727 · Pull Request #169 · ptr727/ProjectTemplate · GitHub
Skip to content

check-upstream-version-task: structured multi-key JSON state - #169

Merged
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state
Jun 21, 2026
Merged

check-upstream-version-task: structured multi-key JSON state#169
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Closes#168.

Raised by ptr727/ESPHome-NonRoot while re-syncing from #167: the canonical check-upstream-version-task.yml serialized only a single bare-string version, so a wrapper pinning several upstream components (ESPHome-NonRoot pins both esphome and the device-builder) could not converge on it and kept a bespoke tracker.

Change

  • Structured state file. The resolver now prints a JSON object of name -> version; the task normalizes it (sorted keys, pretty) and writes it as the canonical state file. One key for the common single-version case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the build by key. This also makes the upstream-version.json extension honest.
  • Changed-key summary. The bump PR title/body are diffed against the prior state and name only the keys that actually moved. The trivial single-version case still renders Update upstream version to X; multi-key renders Update upstream versions: esphome to 2026.7.0 plus a per-component body list.
  • Robustness. Missing/corrupt state diffs cleanly against an empty object (first run works); a resolver that prints non-object output fails with a clear contract message; an unchanged object yields no diff so create-pull-request opens nothing.
  • Docs.AGENTS.md wrapper-repo description updated to the JSON name -> version contract.
  • Workspace. Swapped gruntfuggly.todo-tree for fanaticpythoner.better-todo-tree in DotNet.code-workspace (bundled per request).

The merge-bot keys only on branch refs (upstream-version-<base>), so it needs no change.

Validation

Ran the resolve/compose logic locally across single-key first-run, multi-key first-run, partial move (one of two changed), no-change (empty diff → no PR), and malformed output (rejected). YAML validated.

🤖 Generated with Claude Code

The canonical upstream-version tracker serialized only a single bare string
(resolver printed one line; state file written raw), so a wrapper pinning more
than one upstream component could not converge on it and kept a bespoke tracker.
Make the resolver print a JSON object of name -> version and write it as the
canonical (sorted, pretty) state file: one key for the common single-version
case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the
build by key. This also makes the upstream-version.json extension honest. The
bump PR title/body now name only the keys that actually moved, diffed against
the prior state. Update the AGENTS.md wrapper-repo description to match.
Also swap the todo-tree workspace extension for fanaticpythoner.better-todo-tree.
Closes#168
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CopilotAI review requested due to automatic review settings June 21, 2026 20:12

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the upstream-version tracking reusable workflow to support wrapper repos that need to pin multiple upstream components by moving from a single string state to a structured JSON object, and aligns documentation/workspace defaults with that new contract.

Changes:

  • Switch .github/workflows/check-upstream-version-task.yml to accept resolver output as a JSON object (name -> version), normalize it, and generate PR title/body from per-key diffs.
  • Document the new multi-key JSON state contract in AGENTS.md.
  • Update DotNet.code-workspace extension recommendations (swap TODO-tree extension).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

FileDescription
DotNet.code-workspaceReplaces the TODO tree extension recommendation.
AGENTS.mdUpdates wrapper-repo guidance to the new JSON name -> version state contract.
.github/workflows/check-upstream-version-task.ymlImplements structured JSON state parsing/normalization and changed-key PR title/body composition.

Comment thread.github/workflows/check-upstream-version-task.yml
Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Require the resolver object to be non-empty with all-string values so malformed
output fails fast instead of committing state the build cannot consume. Diff
across the union of old+new keys so a removed key is reported (carries null);
title a key-less reserialization as a canonicalize-only change rather than an
empty "Update upstream versions: ".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
A state file that was valid JSON but not an object (string/array/number) passed
the existing-file guard and then broke the `$old + $new` union diff. Accept the
prior state only when it parses as an object; otherwise diff against `{}`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Comment thread.github/workflows/check-upstream-version-task.yml
A version string carrying an embedded newline would corrupt the single-line
title=/body GITHUB_OUTPUT, so require keys and values to be single-line. Also
correct the state-write comment: a differently-formatted-but-identical prior
file does change and opens a canonicalize-only PR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit 7566c39 into developJun 21, 2026
9 checks passed
@ptr727
ptr727 deleted the upstream-version-multikey-state branch June 21, 2026 20:33
ptr727 added a commit to ptr727/ESPHome-NonRoot that referenced this pull request Jun 21, 2026
* Adopt canonical upstream-version tracker for multi-key state
Replace the bespoke check-esphome-version.yml with the carried
check-upstream-version-task.yml plus a thin scheduled entry-point
(check-upstream-version.yml) whose resolver prints the esphome and
device-builder versions as a JSON object. Rename the state file
esphome-version.json -> upstream-version.json (keyed esphome and
device_builder, sorted JSON) and point build-docker-task.yml, the
merge-bot refs (upstream-version-<base>), and the PR paths-filter at it.
Converges on ptr727/ProjectTemplate#169, which added structured
multi-key state to the canonical task per the gap filed in #168.
Closes#66.
* Write upstream-version state file as CRLF per template fix
Re-sync the carried check-upstream-version-task.yml to write the state
file as CRLF (jq emits LF), honoring .editorconfig's .json rule, and
convert upstream-version.json to CRLF to match. Converges on
ptr727/ProjectTemplate#172, which resolved the LF-vs-CRLF state-file
nuance filed in #170.
* Harden upstream resolver curl error reporting
Add --show-error/--location to the PyPI curl calls and emit ::error::
annotations on resolve failure, so a failed scheduled run surfaces a
clear cause. Addresses Copilot review feedback on PR #67.
* Use product names in resolver errors and tracker wording
Reference ESPHome and esphome-device-builder (the PyPI/product names) in
the resolve-failure messages, and update the remaining "ESPHome-version
bump" mention in AGENTS.md to "upstream-version bump". Addresses Copilot
review feedback on PR #67.
ptr727 added a commit that referenced this pull request Jun 22, 2026
… quota (#180)
Promote accumulated `develop` work to `main` so derived repos can
re-sync from `main` (the stable ref) rather than tracking `develop`.
Docs / CI / config only — no `version.json` bump (no functional change).
## Notable contents
- **Consolidate code style + carry contract** (#178, closes#175): one
root `CODESTYLE.md` (General → .NET → Python, droppable sections);
`PyPiLibrary/CODESTYLE.md` removed; `CODESTYLE.md` +
`.vscode/tasks.json` added to the verbatim-carry list; official-tooling
casing (`.Net*` → `.NET*`); clean-compile rule; brownfield/suppression
scope hierarchy; `dependsOrder: sequence` on the `.NET Format` task.
- **Clarify project-rule home + harden Copilot runbook** (#173): project
conventions/API contracts live in `AGENTS.md`, not
`.github/copilot-instructions.md`; a no-inline-comment review is a clean
pass; poll for the auto-review before self-triggering.
- **Cut Actions artifact-storage quota usage** (#179): PR smoke builds
no longer upload artifacts nothing consumes.
- Plus prior develop work: docs/comment cleanup (#167),
`check-upstream-version-task` structured multi-key state (#169) + CRLF
state file (#172), `publish-docker-readme-task`, and routine codegen
updates.
## Notes
- develop → main is **merge-commit only** (preserves develop's commit
list as a second-parent reference on `main`).
- Merging closes#173 and #175 (their `Closes` keywords reach the
default branch).
- After merge, the downstream re-sync issues (each updated with the
current state) can point at `main`.
Sign up for freeto 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.

2 participants

@ptr727
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' check-upstream-version-task: structured multi-key JSON state by ptr727 · Pull Request #169 · ptr727/ProjectTemplate · GitHub
Skip to content

check-upstream-version-task: structured multi-key JSON state - #169

Merged
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state
Jun 21, 2026
Merged

check-upstream-version-task: structured multi-key JSON state#169
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Closes#168.

Raised by ptr727/ESPHome-NonRoot while re-syncing from #167: the canonical check-upstream-version-task.yml serialized only a single bare-string version, so a wrapper pinning several upstream components (ESPHome-NonRoot pins both esphome and the device-builder) could not converge on it and kept a bespoke tracker.

Change

  • Structured state file. The resolver now prints a JSON object of name -> version; the task normalizes it (sorted keys, pretty) and writes it as the canonical state file. One key for the common single-version case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the build by key. This also makes the upstream-version.json extension honest.
  • Changed-key summary. The bump PR title/body are diffed against the prior state and name only the keys that actually moved. The trivial single-version case still renders Update upstream version to X; multi-key renders Update upstream versions: esphome to 2026.7.0 plus a per-component body list.
  • Robustness. Missing/corrupt state diffs cleanly against an empty object (first run works); a resolver that prints non-object output fails with a clear contract message; an unchanged object yields no diff so create-pull-request opens nothing.
  • Docs.AGENTS.md wrapper-repo description updated to the JSON name -> version contract.
  • Workspace. Swapped gruntfuggly.todo-tree for fanaticpythoner.better-todo-tree in DotNet.code-workspace (bundled per request).

The merge-bot keys only on branch refs (upstream-version-<base>), so it needs no change.

Validation

Ran the resolve/compose logic locally across single-key first-run, multi-key first-run, partial move (one of two changed), no-change (empty diff → no PR), and malformed output (rejected). YAML validated.

🤖 Generated with Claude Code

The canonical upstream-version tracker serialized only a single bare string
(resolver printed one line; state file written raw), so a wrapper pinning more
than one upstream component could not converge on it and kept a bespoke tracker.
Make the resolver print a JSON object of name -> version and write it as the
canonical (sorted, pretty) state file: one key for the common single-version
case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the
build by key. This also makes the upstream-version.json extension honest. The
bump PR title/body now name only the keys that actually moved, diffed against
the prior state. Update the AGENTS.md wrapper-repo description to match.
Also swap the todo-tree workspace extension for fanaticpythoner.better-todo-tree.
Closes#168
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CopilotAI review requested due to automatic review settings June 21, 2026 20:12

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the upstream-version tracking reusable workflow to support wrapper repos that need to pin multiple upstream components by moving from a single string state to a structured JSON object, and aligns documentation/workspace defaults with that new contract.

Changes:

  • Switch .github/workflows/check-upstream-version-task.yml to accept resolver output as a JSON object (name -> version), normalize it, and generate PR title/body from per-key diffs.
  • Document the new multi-key JSON state contract in AGENTS.md.
  • Update DotNet.code-workspace extension recommendations (swap TODO-tree extension).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

FileDescription
DotNet.code-workspaceReplaces the TODO tree extension recommendation.
AGENTS.mdUpdates wrapper-repo guidance to the new JSON name -> version state contract.
.github/workflows/check-upstream-version-task.ymlImplements structured JSON state parsing/normalization and changed-key PR title/body composition.

Comment thread.github/workflows/check-upstream-version-task.yml
Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Require the resolver object to be non-empty with all-string values so malformed
output fails fast instead of committing state the build cannot consume. Diff
across the union of old+new keys so a removed key is reported (carries null);
title a key-less reserialization as a canonicalize-only change rather than an
empty "Update upstream versions: ".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
A state file that was valid JSON but not an object (string/array/number) passed
the existing-file guard and then broke the `$old + $new` union diff. Accept the
prior state only when it parses as an object; otherwise diff against `{}`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Comment thread.github/workflows/check-upstream-version-task.yml
A version string carrying an embedded newline would corrupt the single-line
title=/body GITHUB_OUTPUT, so require keys and values to be single-line. Also
correct the state-write comment: a differently-formatted-but-identical prior
file does change and opens a canonicalize-only PR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit 7566c39 into developJun 21, 2026
9 checks passed
@ptr727
ptr727 deleted the upstream-version-multikey-state branch June 21, 2026 20:33
ptr727 added a commit to ptr727/ESPHome-NonRoot that referenced this pull request Jun 21, 2026
* Adopt canonical upstream-version tracker for multi-key state
Replace the bespoke check-esphome-version.yml with the carried
check-upstream-version-task.yml plus a thin scheduled entry-point
(check-upstream-version.yml) whose resolver prints the esphome and
device-builder versions as a JSON object. Rename the state file
esphome-version.json -> upstream-version.json (keyed esphome and
device_builder, sorted JSON) and point build-docker-task.yml, the
merge-bot refs (upstream-version-<base>), and the PR paths-filter at it.
Converges on ptr727/ProjectTemplate#169, which added structured
multi-key state to the canonical task per the gap filed in #168.
Closes#66.
* Write upstream-version state file as CRLF per template fix
Re-sync the carried check-upstream-version-task.yml to write the state
file as CRLF (jq emits LF), honoring .editorconfig's .json rule, and
convert upstream-version.json to CRLF to match. Converges on
ptr727/ProjectTemplate#172, which resolved the LF-vs-CRLF state-file
nuance filed in #170.
* Harden upstream resolver curl error reporting
Add --show-error/--location to the PyPI curl calls and emit ::error::
annotations on resolve failure, so a failed scheduled run surfaces a
clear cause. Addresses Copilot review feedback on PR #67.
* Use product names in resolver errors and tracker wording
Reference ESPHome and esphome-device-builder (the PyPI/product names) in
the resolve-failure messages, and update the remaining "ESPHome-version
bump" mention in AGENTS.md to "upstream-version bump". Addresses Copilot
review feedback on PR #67.
ptr727 added a commit that referenced this pull request Jun 22, 2026
… quota (#180)
Promote accumulated `develop` work to `main` so derived repos can
re-sync from `main` (the stable ref) rather than tracking `develop`.
Docs / CI / config only — no `version.json` bump (no functional change).
## Notable contents
- **Consolidate code style + carry contract** (#178, closes#175): one
root `CODESTYLE.md` (General → .NET → Python, droppable sections);
`PyPiLibrary/CODESTYLE.md` removed; `CODESTYLE.md` +
`.vscode/tasks.json` added to the verbatim-carry list; official-tooling
casing (`.Net*` → `.NET*`); clean-compile rule; brownfield/suppression
scope hierarchy; `dependsOrder: sequence` on the `.NET Format` task.
- **Clarify project-rule home + harden Copilot runbook** (#173): project
conventions/API contracts live in `AGENTS.md`, not
`.github/copilot-instructions.md`; a no-inline-comment review is a clean
pass; poll for the auto-review before self-triggering.
- **Cut Actions artifact-storage quota usage** (#179): PR smoke builds
no longer upload artifacts nothing consumes.
- Plus prior develop work: docs/comment cleanup (#167),
`check-upstream-version-task` structured multi-key state (#169) + CRLF
state file (#172), `publish-docker-readme-task`, and routine codegen
updates.
## Notes
- develop → main is **merge-commit only** (preserves develop's commit
list as a second-parent reference on `main`).
- Merging closes#173 and #175 (their `Closes` keywords reach the
default branch).
- After merge, the downstream re-sync issues (each updated with the
current state) can point at `main`.
Sign up for freeto 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.

2 participants

@ptr727
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' check-upstream-version-task: structured multi-key JSON state by ptr727 · Pull Request #169 · ptr727/ProjectTemplate · GitHub
Skip to content

check-upstream-version-task: structured multi-key JSON state - #169

Merged
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state
Jun 21, 2026
Merged

check-upstream-version-task: structured multi-key JSON state#169
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Closes#168.

Raised by ptr727/ESPHome-NonRoot while re-syncing from #167: the canonical check-upstream-version-task.yml serialized only a single bare-string version, so a wrapper pinning several upstream components (ESPHome-NonRoot pins both esphome and the device-builder) could not converge on it and kept a bespoke tracker.

Change

  • Structured state file. The resolver now prints a JSON object of name -> version; the task normalizes it (sorted keys, pretty) and writes it as the canonical state file. One key for the common single-version case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the build by key. This also makes the upstream-version.json extension honest.
  • Changed-key summary. The bump PR title/body are diffed against the prior state and name only the keys that actually moved. The trivial single-version case still renders Update upstream version to X; multi-key renders Update upstream versions: esphome to 2026.7.0 plus a per-component body list.
  • Robustness. Missing/corrupt state diffs cleanly against an empty object (first run works); a resolver that prints non-object output fails with a clear contract message; an unchanged object yields no diff so create-pull-request opens nothing.
  • Docs.AGENTS.md wrapper-repo description updated to the JSON name -> version contract.
  • Workspace. Swapped gruntfuggly.todo-tree for fanaticpythoner.better-todo-tree in DotNet.code-workspace (bundled per request).

The merge-bot keys only on branch refs (upstream-version-<base>), so it needs no change.

Validation

Ran the resolve/compose logic locally across single-key first-run, multi-key first-run, partial move (one of two changed), no-change (empty diff → no PR), and malformed output (rejected). YAML validated.

🤖 Generated with Claude Code

The canonical upstream-version tracker serialized only a single bare string
(resolver printed one line; state file written raw), so a wrapper pinning more
than one upstream component could not converge on it and kept a bespoke tracker.
Make the resolver print a JSON object of name -> version and write it as the
canonical (sorted, pretty) state file: one key for the common single-version
case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the
build by key. This also makes the upstream-version.json extension honest. The
bump PR title/body now name only the keys that actually moved, diffed against
the prior state. Update the AGENTS.md wrapper-repo description to match.
Also swap the todo-tree workspace extension for fanaticpythoner.better-todo-tree.
Closes#168
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CopilotAI review requested due to automatic review settings June 21, 2026 20:12

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the upstream-version tracking reusable workflow to support wrapper repos that need to pin multiple upstream components by moving from a single string state to a structured JSON object, and aligns documentation/workspace defaults with that new contract.

Changes:

  • Switch .github/workflows/check-upstream-version-task.yml to accept resolver output as a JSON object (name -> version), normalize it, and generate PR title/body from per-key diffs.
  • Document the new multi-key JSON state contract in AGENTS.md.
  • Update DotNet.code-workspace extension recommendations (swap TODO-tree extension).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

FileDescription
DotNet.code-workspaceReplaces the TODO tree extension recommendation.
AGENTS.mdUpdates wrapper-repo guidance to the new JSON name -> version state contract.
.github/workflows/check-upstream-version-task.ymlImplements structured JSON state parsing/normalization and changed-key PR title/body composition.

Comment thread.github/workflows/check-upstream-version-task.yml
Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Require the resolver object to be non-empty with all-string values so malformed
output fails fast instead of committing state the build cannot consume. Diff
across the union of old+new keys so a removed key is reported (carries null);
title a key-less reserialization as a canonicalize-only change rather than an
empty "Update upstream versions: ".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
A state file that was valid JSON but not an object (string/array/number) passed
the existing-file guard and then broke the `$old + $new` union diff. Accept the
prior state only when it parses as an object; otherwise diff against `{}`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Comment thread.github/workflows/check-upstream-version-task.yml
A version string carrying an embedded newline would corrupt the single-line
title=/body GITHUB_OUTPUT, so require keys and values to be single-line. Also
correct the state-write comment: a differently-formatted-but-identical prior
file does change and opens a canonicalize-only PR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit 7566c39 into developJun 21, 2026
9 checks passed
@ptr727
ptr727 deleted the upstream-version-multikey-state branch June 21, 2026 20:33
ptr727 added a commit to ptr727/ESPHome-NonRoot that referenced this pull request Jun 21, 2026
* Adopt canonical upstream-version tracker for multi-key state
Replace the bespoke check-esphome-version.yml with the carried
check-upstream-version-task.yml plus a thin scheduled entry-point
(check-upstream-version.yml) whose resolver prints the esphome and
device-builder versions as a JSON object. Rename the state file
esphome-version.json -> upstream-version.json (keyed esphome and
device_builder, sorted JSON) and point build-docker-task.yml, the
merge-bot refs (upstream-version-<base>), and the PR paths-filter at it.
Converges on ptr727/ProjectTemplate#169, which added structured
multi-key state to the canonical task per the gap filed in #168.
Closes#66.
* Write upstream-version state file as CRLF per template fix
Re-sync the carried check-upstream-version-task.yml to write the state
file as CRLF (jq emits LF), honoring .editorconfig's .json rule, and
convert upstream-version.json to CRLF to match. Converges on
ptr727/ProjectTemplate#172, which resolved the LF-vs-CRLF state-file
nuance filed in #170.
* Harden upstream resolver curl error reporting
Add --show-error/--location to the PyPI curl calls and emit ::error::
annotations on resolve failure, so a failed scheduled run surfaces a
clear cause. Addresses Copilot review feedback on PR #67.
* Use product names in resolver errors and tracker wording
Reference ESPHome and esphome-device-builder (the PyPI/product names) in
the resolve-failure messages, and update the remaining "ESPHome-version
bump" mention in AGENTS.md to "upstream-version bump". Addresses Copilot
review feedback on PR #67.
ptr727 added a commit that referenced this pull request Jun 22, 2026
… quota (#180)
Promote accumulated `develop` work to `main` so derived repos can
re-sync from `main` (the stable ref) rather than tracking `develop`.
Docs / CI / config only — no `version.json` bump (no functional change).
## Notable contents
- **Consolidate code style + carry contract** (#178, closes#175): one
root `CODESTYLE.md` (General → .NET → Python, droppable sections);
`PyPiLibrary/CODESTYLE.md` removed; `CODESTYLE.md` +
`.vscode/tasks.json` added to the verbatim-carry list; official-tooling
casing (`.Net*` → `.NET*`); clean-compile rule; brownfield/suppression
scope hierarchy; `dependsOrder: sequence` on the `.NET Format` task.
- **Clarify project-rule home + harden Copilot runbook** (#173): project
conventions/API contracts live in `AGENTS.md`, not
`.github/copilot-instructions.md`; a no-inline-comment review is a clean
pass; poll for the auto-review before self-triggering.
- **Cut Actions artifact-storage quota usage** (#179): PR smoke builds
no longer upload artifacts nothing consumes.
- Plus prior develop work: docs/comment cleanup (#167),
`check-upstream-version-task` structured multi-key state (#169) + CRLF
state file (#172), `publish-docker-readme-task`, and routine codegen
updates.
## Notes
- develop → main is **merge-commit only** (preserves develop's commit
list as a second-parent reference on `main`).
- Merging closes#173 and #175 (their `Closes` keywords reach the
default branch).
- After merge, the downstream re-sync issues (each updated with the
current state) can point at `main`.
Sign up for freeto 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.

2 participants

@ptr727
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' check-upstream-version-task: structured multi-key JSON state by ptr727 · Pull Request #169 · ptr727/ProjectTemplate · GitHub
Skip to content

check-upstream-version-task: structured multi-key JSON state - #169

Merged
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state
Jun 21, 2026
Merged

check-upstream-version-task: structured multi-key JSON state#169
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Closes#168.

Raised by ptr727/ESPHome-NonRoot while re-syncing from #167: the canonical check-upstream-version-task.yml serialized only a single bare-string version, so a wrapper pinning several upstream components (ESPHome-NonRoot pins both esphome and the device-builder) could not converge on it and kept a bespoke tracker.

Change

  • Structured state file. The resolver now prints a JSON object of name -> version; the task normalizes it (sorted keys, pretty) and writes it as the canonical state file. One key for the common single-version case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the build by key. This also makes the upstream-version.json extension honest.
  • Changed-key summary. The bump PR title/body are diffed against the prior state and name only the keys that actually moved. The trivial single-version case still renders Update upstream version to X; multi-key renders Update upstream versions: esphome to 2026.7.0 plus a per-component body list.
  • Robustness. Missing/corrupt state diffs cleanly against an empty object (first run works); a resolver that prints non-object output fails with a clear contract message; an unchanged object yields no diff so create-pull-request opens nothing.
  • Docs.AGENTS.md wrapper-repo description updated to the JSON name -> version contract.
  • Workspace. Swapped gruntfuggly.todo-tree for fanaticpythoner.better-todo-tree in DotNet.code-workspace (bundled per request).

The merge-bot keys only on branch refs (upstream-version-<base>), so it needs no change.

Validation

Ran the resolve/compose logic locally across single-key first-run, multi-key first-run, partial move (one of two changed), no-change (empty diff → no PR), and malformed output (rejected). YAML validated.

🤖 Generated with Claude Code

The canonical upstream-version tracker serialized only a single bare string
(resolver printed one line; state file written raw), so a wrapper pinning more
than one upstream component could not converge on it and kept a bespoke tracker.
Make the resolver print a JSON object of name -> version and write it as the
canonical (sorted, pretty) state file: one key for the common single-version
case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the
build by key. This also makes the upstream-version.json extension honest. The
bump PR title/body now name only the keys that actually moved, diffed against
the prior state. Update the AGENTS.md wrapper-repo description to match.
Also swap the todo-tree workspace extension for fanaticpythoner.better-todo-tree.
Closes#168
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CopilotAI review requested due to automatic review settings June 21, 2026 20:12

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the upstream-version tracking reusable workflow to support wrapper repos that need to pin multiple upstream components by moving from a single string state to a structured JSON object, and aligns documentation/workspace defaults with that new contract.

Changes:

  • Switch .github/workflows/check-upstream-version-task.yml to accept resolver output as a JSON object (name -> version), normalize it, and generate PR title/body from per-key diffs.
  • Document the new multi-key JSON state contract in AGENTS.md.
  • Update DotNet.code-workspace extension recommendations (swap TODO-tree extension).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

FileDescription
DotNet.code-workspaceReplaces the TODO tree extension recommendation.
AGENTS.mdUpdates wrapper-repo guidance to the new JSON name -> version state contract.
.github/workflows/check-upstream-version-task.ymlImplements structured JSON state parsing/normalization and changed-key PR title/body composition.

Comment thread.github/workflows/check-upstream-version-task.yml
Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Require the resolver object to be non-empty with all-string values so malformed
output fails fast instead of committing state the build cannot consume. Diff
across the union of old+new keys so a removed key is reported (carries null);
title a key-less reserialization as a canonicalize-only change rather than an
empty "Update upstream versions: ".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
A state file that was valid JSON but not an object (string/array/number) passed
the existing-file guard and then broke the `$old + $new` union diff. Accept the
prior state only when it parses as an object; otherwise diff against `{}`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Comment thread.github/workflows/check-upstream-version-task.yml
A version string carrying an embedded newline would corrupt the single-line
title=/body GITHUB_OUTPUT, so require keys and values to be single-line. Also
correct the state-write comment: a differently-formatted-but-identical prior
file does change and opens a canonicalize-only PR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit 7566c39 into developJun 21, 2026
9 checks passed
@ptr727
ptr727 deleted the upstream-version-multikey-state branch June 21, 2026 20:33
ptr727 added a commit to ptr727/ESPHome-NonRoot that referenced this pull request Jun 21, 2026
* Adopt canonical upstream-version tracker for multi-key state
Replace the bespoke check-esphome-version.yml with the carried
check-upstream-version-task.yml plus a thin scheduled entry-point
(check-upstream-version.yml) whose resolver prints the esphome and
device-builder versions as a JSON object. Rename the state file
esphome-version.json -> upstream-version.json (keyed esphome and
device_builder, sorted JSON) and point build-docker-task.yml, the
merge-bot refs (upstream-version-<base>), and the PR paths-filter at it.
Converges on ptr727/ProjectTemplate#169, which added structured
multi-key state to the canonical task per the gap filed in #168.
Closes#66.
* Write upstream-version state file as CRLF per template fix
Re-sync the carried check-upstream-version-task.yml to write the state
file as CRLF (jq emits LF), honoring .editorconfig's .json rule, and
convert upstream-version.json to CRLF to match. Converges on
ptr727/ProjectTemplate#172, which resolved the LF-vs-CRLF state-file
nuance filed in #170.
* Harden upstream resolver curl error reporting
Add --show-error/--location to the PyPI curl calls and emit ::error::
annotations on resolve failure, so a failed scheduled run surfaces a
clear cause. Addresses Copilot review feedback on PR #67.
* Use product names in resolver errors and tracker wording
Reference ESPHome and esphome-device-builder (the PyPI/product names) in
the resolve-failure messages, and update the remaining "ESPHome-version
bump" mention in AGENTS.md to "upstream-version bump". Addresses Copilot
review feedback on PR #67.
ptr727 added a commit that referenced this pull request Jun 22, 2026
… quota (#180)
Promote accumulated `develop` work to `main` so derived repos can
re-sync from `main` (the stable ref) rather than tracking `develop`.
Docs / CI / config only — no `version.json` bump (no functional change).
## Notable contents
- **Consolidate code style + carry contract** (#178, closes#175): one
root `CODESTYLE.md` (General → .NET → Python, droppable sections);
`PyPiLibrary/CODESTYLE.md` removed; `CODESTYLE.md` +
`.vscode/tasks.json` added to the verbatim-carry list; official-tooling
casing (`.Net*` → `.NET*`); clean-compile rule; brownfield/suppression
scope hierarchy; `dependsOrder: sequence` on the `.NET Format` task.
- **Clarify project-rule home + harden Copilot runbook** (#173): project
conventions/API contracts live in `AGENTS.md`, not
`.github/copilot-instructions.md`; a no-inline-comment review is a clean
pass; poll for the auto-review before self-triggering.
- **Cut Actions artifact-storage quota usage** (#179): PR smoke builds
no longer upload artifacts nothing consumes.
- Plus prior develop work: docs/comment cleanup (#167),
`check-upstream-version-task` structured multi-key state (#169) + CRLF
state file (#172), `publish-docker-readme-task`, and routine codegen
updates.
## Notes
- develop → main is **merge-commit only** (preserves develop's commit
list as a second-parent reference on `main`).
- Merging closes#173 and #175 (their `Closes` keywords reach the
default branch).
- After merge, the downstream re-sync issues (each updated with the
current state) can point at `main`.
Sign up for freeto 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.

2 participants

@ptr727
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); check-upstream-version-task: structured multi-key JSON state by ptr727 · Pull Request #169 · ptr727/ProjectTemplate · GitHub
Skip to content

check-upstream-version-task: structured multi-key JSON state - #169

Merged
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state
Jun 21, 2026
Merged

check-upstream-version-task: structured multi-key JSON state#169
ptr727 merged 4 commits into
developfrom
upstream-version-multikey-state

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Closes#168.

Raised by ptr727/ESPHome-NonRoot while re-syncing from #167: the canonical check-upstream-version-task.yml serialized only a single bare-string version, so a wrapper pinning several upstream components (ESPHome-NonRoot pins both esphome and the device-builder) could not converge on it and kept a bespoke tracker.

Change

  • Structured state file. The resolver now prints a JSON object of name -> version; the task normalizes it (sorted keys, pretty) and writes it as the canonical state file. One key for the common single-version case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the build by key. This also makes the upstream-version.json extension honest.
  • Changed-key summary. The bump PR title/body are diffed against the prior state and name only the keys that actually moved. The trivial single-version case still renders Update upstream version to X; multi-key renders Update upstream versions: esphome to 2026.7.0 plus a per-component body list.
  • Robustness. Missing/corrupt state diffs cleanly against an empty object (first run works); a resolver that prints non-object output fails with a clear contract message; an unchanged object yields no diff so create-pull-request opens nothing.
  • Docs.AGENTS.md wrapper-repo description updated to the JSON name -> version contract.
  • Workspace. Swapped gruntfuggly.todo-tree for fanaticpythoner.better-todo-tree in DotNet.code-workspace (bundled per request).

The merge-bot keys only on branch refs (upstream-version-<base>), so it needs no change.

Validation

Ran the resolve/compose logic locally across single-key first-run, multi-key first-run, partial move (one of two changed), no-change (empty diff → no PR), and malformed output (rejected). YAML validated.

🤖 Generated with Claude Code

The canonical upstream-version tracker serialized only a single bare string
(resolver printed one line; state file written raw), so a wrapper pinning more
than one upstream component could not converge on it and kept a bespoke tracker.
Make the resolver print a JSON object of name -> version and write it as the
canonical (sorted, pretty) state file: one key for the common single-version
case ({"version":"X"}) or N keys for a multi-component wrapper, each read by the
build by key. This also makes the upstream-version.json extension honest. The
bump PR title/body now name only the keys that actually moved, diffed against
the prior state. Update the AGENTS.md wrapper-repo description to match.
Also swap the todo-tree workspace extension for fanaticpythoner.better-todo-tree.
Closes#168
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CopilotAI review requested due to automatic review settings June 21, 2026 20:12

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the upstream-version tracking reusable workflow to support wrapper repos that need to pin multiple upstream components by moving from a single string state to a structured JSON object, and aligns documentation/workspace defaults with that new contract.

Changes:

  • Switch .github/workflows/check-upstream-version-task.yml to accept resolver output as a JSON object (name -> version), normalize it, and generate PR title/body from per-key diffs.
  • Document the new multi-key JSON state contract in AGENTS.md.
  • Update DotNet.code-workspace extension recommendations (swap TODO-tree extension).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

FileDescription
DotNet.code-workspaceReplaces the TODO tree extension recommendation.
AGENTS.mdUpdates wrapper-repo guidance to the new JSON name -> version state contract.
.github/workflows/check-upstream-version-task.ymlImplements structured JSON state parsing/normalization and changed-key PR title/body composition.

Comment thread.github/workflows/check-upstream-version-task.yml
Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Require the resolver object to be non-empty with all-string values so malformed
output fails fast instead of committing state the build cannot consume. Diff
across the union of old+new keys so a removed key is reported (carries null);
title a key-less reserialization as a canonicalize-only change rather than an
empty "Update upstream versions: ".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
A state file that was valid JSON but not an object (string/array/number) passed
the existing-file guard and then broke the `$old + $new` union diff. Accept the
prior state only when it parses as an object; otherwise diff against `{}`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread.github/workflows/check-upstream-version-task.yml Outdated
Comment thread.github/workflows/check-upstream-version-task.yml
A version string carrying an embedded newline would corrupt the single-line
title=/body GITHUB_OUTPUT, so require keys and values to be single-line. Also
correct the state-write comment: a differently-formatted-but-identical prior
file does change and opens a canonicalize-only PR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit 7566c39 into developJun 21, 2026
9 checks passed
@ptr727
ptr727 deleted the upstream-version-multikey-state branch June 21, 2026 20:33
ptr727 added a commit to ptr727/ESPHome-NonRoot that referenced this pull request Jun 21, 2026
* Adopt canonical upstream-version tracker for multi-key state
Replace the bespoke check-esphome-version.yml with the carried
check-upstream-version-task.yml plus a thin scheduled entry-point
(check-upstream-version.yml) whose resolver prints the esphome and
device-builder versions as a JSON object. Rename the state file
esphome-version.json -> upstream-version.json (keyed esphome and
device_builder, sorted JSON) and point build-docker-task.yml, the
merge-bot refs (upstream-version-<base>), and the PR paths-filter at it.
Converges on ptr727/ProjectTemplate#169, which added structured
multi-key state to the canonical task per the gap filed in #168.
Closes#66.
* Write upstream-version state file as CRLF per template fix
Re-sync the carried check-upstream-version-task.yml to write the state
file as CRLF (jq emits LF), honoring .editorconfig's .json rule, and
convert upstream-version.json to CRLF to match. Converges on
ptr727/ProjectTemplate#172, which resolved the LF-vs-CRLF state-file
nuance filed in #170.
* Harden upstream resolver curl error reporting
Add --show-error/--location to the PyPI curl calls and emit ::error::
annotations on resolve failure, so a failed scheduled run surfaces a
clear cause. Addresses Copilot review feedback on PR #67.
* Use product names in resolver errors and tracker wording
Reference ESPHome and esphome-device-builder (the PyPI/product names) in
the resolve-failure messages, and update the remaining "ESPHome-version
bump" mention in AGENTS.md to "upstream-version bump". Addresses Copilot
review feedback on PR #67.
ptr727 added a commit that referenced this pull request Jun 22, 2026
… quota (#180)
Promote accumulated `develop` work to `main` so derived repos can
re-sync from `main` (the stable ref) rather than tracking `develop`.
Docs / CI / config only — no `version.json` bump (no functional change).
## Notable contents
- **Consolidate code style + carry contract** (#178, closes#175): one
root `CODESTYLE.md` (General → .NET → Python, droppable sections);
`PyPiLibrary/CODESTYLE.md` removed; `CODESTYLE.md` +
`.vscode/tasks.json` added to the verbatim-carry list; official-tooling
casing (`.Net*` → `.NET*`); clean-compile rule; brownfield/suppression
scope hierarchy; `dependsOrder: sequence` on the `.NET Format` task.
- **Clarify project-rule home + harden Copilot runbook** (#173): project
conventions/API contracts live in `AGENTS.md`, not
`.github/copilot-instructions.md`; a no-inline-comment review is a clean
pass; poll for the auto-review before self-triggering.
- **Cut Actions artifact-storage quota usage** (#179): PR smoke builds
no longer upload artifacts nothing consumes.
- Plus prior develop work: docs/comment cleanup (#167),
`check-upstream-version-task` structured multi-key state (#169) + CRLF
state file (#172), `publish-docker-readme-task`, and routine codegen
updates.
## Notes
- develop → main is **merge-commit only** (preserves develop's commit
list as a second-parent reference on `main`).
- Merging closes#173 and #175 (their `Closes` keywords reach the
default branch).
- After merge, the downstream re-sync issues (each updated with the
current state) can point at `main`.
Sign up for freeto 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.

2 participants

@ptr727