Convert to two-phase dual-publish release model - #320

Merged
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template
Jun 5, 2026
Merged

Convert to two-phase dual-publish release model#320
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Summary

Convert the project from publish-on-push to the ptr727/ProjectTemplatetwo-phase dual-publish release model, matching the structure already adopted by LanguageTags so future template changes apply as minimal deltas.

  • Phase 1 — PRs smoke-test only.test-pull-request.yml runs unit tests + a paths-filtered smoke build; merges no longer publish.
  • Phase 2 — weekly scheduled publish.publish-release.yml publishes both branches on a Monday 02:00 UTC cron and on manual dispatch, with idempotent no-op republish (skip release if the tag exists, --skip-duplicate on NuGet). Opt-in continuous-release via the PUBLISH_ON_MERGE repo variable.

Changes

  • Reusable workflow set: get-version-task, build-nugetlibrary-task, build-release-task, build-datebadge-task, plus publish-release, test-pull-request, and a branch-aware Dependabot merge-bot-pull-request (squash on develop / merge on main).
  • Removed BuildPublishPipeline.yml and DependabotAutoMerge.yml. NuGet.org-only (dropped the GitHub Packages push). No Docker/executable/PyPI/codegen targets.
  • Central Package Management (Directory.Build.props + Directory.Packages.props).
  • Added AGENTS.md documenting the branching/release/workflow conventions.
  • Reconciled the template's strict analyzers (AnalysisMode All + TreatWarningsAsErrors) with this brownfield library by relaxing specific rules in .editorconfig (each documented inline) and IL3058 via NoWarn; ImplicitUsings cleanup removed now-redundant usings.
  • Normalized line endings to .editorconfig and fixed the .husky/pre-commit shebang to LF + executable.

Maintainer follow-ups (not in this PR)

  • Add CODEGEN_APP_CLIENT_ID / CODEGEN_APP_PRIVATE_KEY (GitHub App) to both Actions and Dependabot secret stores for the merge-bot.
  • Bind the Check pull request workflow status required check to the develop (squash-only) and main (merge-only) rulesets.
  • Leave PUBLISH_ON_MERGE unset for the two-phase default.

🤖 Generated with Claude Code

ptr727 added 2 commits June 4, 2026 18:01
Replace publish-on-push with the ProjectTemplate/LanguageTags two-phase
model: PRs smoke-test only, and publish-release.yml publishes both branches
on a weekly schedule (Mon 02:00 UTC) or manual dispatch, with idempotent
no-op republish. Adopt the reusable workflow set (get-version,
build-nugetlibrary, build-release, build-datebadge), a branch-aware
Dependabot merge-bot, Central Package Management, and an AGENTS.md tracking
the template. NuGet.org-only (drop GitHub Packages); no Docker/exe/PyPI/codegen.
Reconcile the template's strict analyzers (AnalysisMode All +
TreatWarningsAsErrors) with the brownfield library by relaxing specific
rules in .editorconfig and IL3058 via NoWarn, all documented.
Convert the workflow YAML, dependabot.yml, and AGENTS.md (added LF) to CRLF
per .editorconfig, and make .husky/pre-commit LF + executable so its shebang
execs on Linux/WSL. Add an .editorconfig rule pinning the hook to LF.
CopilotAI review requested due to automatic review settings June 5, 2026 01:14

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

Migrates the repository’s CI/CD from the previous publish-on-push pipeline to the ProjectTemplate-aligned two-phase dual-publish model (PR smoke-test only; scheduled/manual publish of both main and develop), while introducing Central Package Management and codifying release/workflow conventions.

Changes:

  • Replaces the legacy build/publish workflows with a reusable-task workflow set, a PR-only test/smoke workflow, and a scheduled/manual publisher that can optionally publish on merge via PUBLISH_ON_MERGE.
  • Introduces Central Package Management (Directory.Build.props, Directory.Packages.props) and adjusts project files/using directives to rely on shared settings + implicit usings.
  • Adds/updates repo process documentation and configuration (AGENTS.md, .editorconfig, hook shebang/line-endings, .gitignore, README badge).

Reviewed changes

Copilot reviewed 38 out of 40 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
UtilitiesTests/UtilitiesTests.csprojRemoves per-project TFM/analyzer/version pinning to rely on shared build props + central package versions.
UtilitiesTests/UtilitiesTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringHistoryTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/FileExAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ExtensionsTests.csUpdates null-argument extension tests and removes redundant usings as part of analyzer/implicit-using cleanup.
UtilitiesTests/DownloadTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/DownloadAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ConsoleTests.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Utilities.csprojMoves analyzer/TFM/nullable to shared props; adds AOT warning suppression for IL3058; uses CPM.
Utilities/StringHistory.csRemoves redundant explicit using now covered by implicit usings.
Utilities/StringCompression.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Format.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileExOptions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Extensions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Download.csRemoves redundant explicit using now covered by implicit usings.
Utilities/ConsoleEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/CommandLineEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities.slnxAdds new solution items for CPM + agent/process docs + new workflows; removes legacy workflow entries.
Sandbox/Sandbox.csprojAligns sandbox build props with shared settings + CPM; suppresses IL3058 similarly.
Sandbox/Program.csMinor cleanup to use AppContext and rely on implicit usings.
README.mdUpdates workflow-status badge to point at the new publisher workflow.
Directory.Packages.propsAdds central package version definitions for NuGet, tests, and Serilog dependencies.
Directory.Build.propsAdds shared build settings (TFM, analyzers, WarningsAsErrors, artifacts path, CPM enablement).
AGENTS.mdDocuments branching rules, release model, and workflow conventions for maintainers/agents.
.husky/pre-commitNormalizes shebang/line-endings to ensure hook runs on POSIX shells.
.gitignoreIgnores .artifacts folder produced by the shared ArtifactsPath.
.github/workflows/test-pull-request.ymlNew PR workflow: unit tests + paths-filter-gated smoke build + required-status aggregator job.
.github/workflows/publish-release.ymlNew publisher: scheduled/manual dual-branch publish, optional push-publish gated by PUBLISH_ON_MERGE.
.github/workflows/merge-bot-pull-request.ymlNew Dependabot merge-bot using App token and branch-aware merge method.
.github/workflows/get-version-task.ymlNew reusable workflow to compute NBGV version metadata with a pinned checkout ref.
.github/workflows/build-release-task.ymlNew reusable orchestrator tying versioning, NuGet build/push, and GitHub release creation together.
.github/workflows/build-nugetlibrary-task.ymlNew reusable NuGet build/push + artifact upload task, branch-config aware.
.github/workflows/build-datebadge-task.ymlNew reusable BYOB badge task gated to main.
.github/workflows/DependabotAutoMerge.ymlRemoves legacy Dependabot auto-merge workflow in favor of merge-bot model.
.github/workflows/BuildPublishPipeline.ymlRemoves legacy publish-on-push pipeline in favor of two-phase model.
.github/dependabot.ymlUpdates Dependabot config to open updates against both main and develop.
.editorconfigAdds LF override for husky hook + documents analyzer relaxations for brownfield code under strict analysis mode.

Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment thread.github/workflows/build-datebadge-task.yml
@ptr727
ptr727 merged commit 0e65bd2 into developJun 5, 2026
7 checks passed
@ptr727
ptr727 deleted the convert-dualpublish-template branch June 5, 2026 01:28
ptr727 added a commit that referenced this pull request Jun 5, 2026
## Summary
Land the two-phase dual-publish model on `main`, with **fully signed &
GitHub-verified history**. This is `main` merged with `develop`
(`0f1616d`), the one-time old→new structural conflicts resolved in
**develop's favour**, and the **max dependency/tool versions** taken so
`main`'s newer Dependabot bumps are not regressed.
All introduced commits are committer = `Pieter Viljoen
<ptr727@users.noreply.github.com>` and verified, satisfying
`required_signatures` (supersedes #322/#323, which carried unverifiable
web-flow-committed history).
### Dependency reconciliation (max of develop/main)
| Package / tool | Version |
| --- | --- |
| Microsoft.SourceLink.GitHub | 10.0.201 |
| Serilog | 4.3.1 |
| Microsoft.NET.Test.Sdk | 18.4.0 |
| xunit.analyzers | 1.27.0 |
| csharpier (tool) | 1.2.6 |
| husky (tool) | 0.9.1 |
Net diff vs `develop` is only the six version bumps above. See #320 for
the full change description.
## Maintainer follow-ups (after merge)
- Add `CODEGEN_APP_CLIENT_ID` / `CODEGEN_APP_PRIVATE_KEY` (GitHub App)
to **both** Actions and Dependabot secret stores for the merge-bot.
- Let Dependabot bring `develop`'s deps up to match (or open a small
sync PR).
- Kick off the first publish via **Actions → publish-release.yml → Run
workflow** once secrets are in.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n 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;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Convert to two-phase dual-publish release model - #320

Merged
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template
Jun 5, 2026
Merged

Convert to two-phase dual-publish release model#320
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Summary

Convert the project from publish-on-push to the ptr727/ProjectTemplatetwo-phase dual-publish release model, matching the structure already adopted by LanguageTags so future template changes apply as minimal deltas.

  • Phase 1 — PRs smoke-test only.test-pull-request.yml runs unit tests + a paths-filtered smoke build; merges no longer publish.
  • Phase 2 — weekly scheduled publish.publish-release.yml publishes both branches on a Monday 02:00 UTC cron and on manual dispatch, with idempotent no-op republish (skip release if the tag exists, --skip-duplicate on NuGet). Opt-in continuous-release via the PUBLISH_ON_MERGE repo variable.

Changes

  • Reusable workflow set: get-version-task, build-nugetlibrary-task, build-release-task, build-datebadge-task, plus publish-release, test-pull-request, and a branch-aware Dependabot merge-bot-pull-request (squash on develop / merge on main).
  • Removed BuildPublishPipeline.yml and DependabotAutoMerge.yml. NuGet.org-only (dropped the GitHub Packages push). No Docker/executable/PyPI/codegen targets.
  • Central Package Management (Directory.Build.props + Directory.Packages.props).
  • Added AGENTS.md documenting the branching/release/workflow conventions.
  • Reconciled the template's strict analyzers (AnalysisMode All + TreatWarningsAsErrors) with this brownfield library by relaxing specific rules in .editorconfig (each documented inline) and IL3058 via NoWarn; ImplicitUsings cleanup removed now-redundant usings.
  • Normalized line endings to .editorconfig and fixed the .husky/pre-commit shebang to LF + executable.

Maintainer follow-ups (not in this PR)

  • Add CODEGEN_APP_CLIENT_ID / CODEGEN_APP_PRIVATE_KEY (GitHub App) to both Actions and Dependabot secret stores for the merge-bot.
  • Bind the Check pull request workflow status required check to the develop (squash-only) and main (merge-only) rulesets.
  • Leave PUBLISH_ON_MERGE unset for the two-phase default.

🤖 Generated with Claude Code

ptr727 added 2 commits June 4, 2026 18:01
Replace publish-on-push with the ProjectTemplate/LanguageTags two-phase
model: PRs smoke-test only, and publish-release.yml publishes both branches
on a weekly schedule (Mon 02:00 UTC) or manual dispatch, with idempotent
no-op republish. Adopt the reusable workflow set (get-version,
build-nugetlibrary, build-release, build-datebadge), a branch-aware
Dependabot merge-bot, Central Package Management, and an AGENTS.md tracking
the template. NuGet.org-only (drop GitHub Packages); no Docker/exe/PyPI/codegen.
Reconcile the template's strict analyzers (AnalysisMode All +
TreatWarningsAsErrors) with the brownfield library by relaxing specific
rules in .editorconfig and IL3058 via NoWarn, all documented.
Convert the workflow YAML, dependabot.yml, and AGENTS.md (added LF) to CRLF
per .editorconfig, and make .husky/pre-commit LF + executable so its shebang
execs on Linux/WSL. Add an .editorconfig rule pinning the hook to LF.
CopilotAI review requested due to automatic review settings June 5, 2026 01:14

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

Migrates the repository’s CI/CD from the previous publish-on-push pipeline to the ProjectTemplate-aligned two-phase dual-publish model (PR smoke-test only; scheduled/manual publish of both main and develop), while introducing Central Package Management and codifying release/workflow conventions.

Changes:

  • Replaces the legacy build/publish workflows with a reusable-task workflow set, a PR-only test/smoke workflow, and a scheduled/manual publisher that can optionally publish on merge via PUBLISH_ON_MERGE.
  • Introduces Central Package Management (Directory.Build.props, Directory.Packages.props) and adjusts project files/using directives to rely on shared settings + implicit usings.
  • Adds/updates repo process documentation and configuration (AGENTS.md, .editorconfig, hook shebang/line-endings, .gitignore, README badge).

Reviewed changes

Copilot reviewed 38 out of 40 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
UtilitiesTests/UtilitiesTests.csprojRemoves per-project TFM/analyzer/version pinning to rely on shared build props + central package versions.
UtilitiesTests/UtilitiesTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringHistoryTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/FileExAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ExtensionsTests.csUpdates null-argument extension tests and removes redundant usings as part of analyzer/implicit-using cleanup.
UtilitiesTests/DownloadTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/DownloadAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ConsoleTests.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Utilities.csprojMoves analyzer/TFM/nullable to shared props; adds AOT warning suppression for IL3058; uses CPM.
Utilities/StringHistory.csRemoves redundant explicit using now covered by implicit usings.
Utilities/StringCompression.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Format.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileExOptions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Extensions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Download.csRemoves redundant explicit using now covered by implicit usings.
Utilities/ConsoleEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/CommandLineEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities.slnxAdds new solution items for CPM + agent/process docs + new workflows; removes legacy workflow entries.
Sandbox/Sandbox.csprojAligns sandbox build props with shared settings + CPM; suppresses IL3058 similarly.
Sandbox/Program.csMinor cleanup to use AppContext and rely on implicit usings.
README.mdUpdates workflow-status badge to point at the new publisher workflow.
Directory.Packages.propsAdds central package version definitions for NuGet, tests, and Serilog dependencies.
Directory.Build.propsAdds shared build settings (TFM, analyzers, WarningsAsErrors, artifacts path, CPM enablement).
AGENTS.mdDocuments branching rules, release model, and workflow conventions for maintainers/agents.
.husky/pre-commitNormalizes shebang/line-endings to ensure hook runs on POSIX shells.
.gitignoreIgnores .artifacts folder produced by the shared ArtifactsPath.
.github/workflows/test-pull-request.ymlNew PR workflow: unit tests + paths-filter-gated smoke build + required-status aggregator job.
.github/workflows/publish-release.ymlNew publisher: scheduled/manual dual-branch publish, optional push-publish gated by PUBLISH_ON_MERGE.
.github/workflows/merge-bot-pull-request.ymlNew Dependabot merge-bot using App token and branch-aware merge method.
.github/workflows/get-version-task.ymlNew reusable workflow to compute NBGV version metadata with a pinned checkout ref.
.github/workflows/build-release-task.ymlNew reusable orchestrator tying versioning, NuGet build/push, and GitHub release creation together.
.github/workflows/build-nugetlibrary-task.ymlNew reusable NuGet build/push + artifact upload task, branch-config aware.
.github/workflows/build-datebadge-task.ymlNew reusable BYOB badge task gated to main.
.github/workflows/DependabotAutoMerge.ymlRemoves legacy Dependabot auto-merge workflow in favor of merge-bot model.
.github/workflows/BuildPublishPipeline.ymlRemoves legacy publish-on-push pipeline in favor of two-phase model.
.github/dependabot.ymlUpdates Dependabot config to open updates against both main and develop.
.editorconfigAdds LF override for husky hook + documents analyzer relaxations for brownfield code under strict analysis mode.

Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment thread.github/workflows/build-datebadge-task.yml
@ptr727
ptr727 merged commit 0e65bd2 into developJun 5, 2026
7 checks passed
@ptr727
ptr727 deleted the convert-dualpublish-template branch June 5, 2026 01:28
ptr727 added a commit that referenced this pull request Jun 5, 2026
## Summary
Land the two-phase dual-publish model on `main`, with **fully signed &
GitHub-verified history**. This is `main` merged with `develop`
(`0f1616d`), the one-time old→new structural conflicts resolved in
**develop's favour**, and the **max dependency/tool versions** taken so
`main`'s newer Dependabot bumps are not regressed.
All introduced commits are committer = `Pieter Viljoen
<ptr727@users.noreply.github.com>` and verified, satisfying
`required_signatures` (supersedes #322/#323, which carried unverifiable
web-flow-committed history).
### Dependency reconciliation (max of develop/main)
| Package / tool | Version |
| --- | --- |
| Microsoft.SourceLink.GitHub | 10.0.201 |
| Serilog | 4.3.1 |
| Microsoft.NET.Test.Sdk | 18.4.0 |
| xunit.analyzers | 1.27.0 |
| csharpier (tool) | 1.2.6 |
| husky (tool) | 0.9.1 |
Net diff vs `develop` is only the six version bumps above. See #320 for
the full change description.
## Maintainer follow-ups (after merge)
- Add `CODEGEN_APP_CLIENT_ID` / `CODEGEN_APP_PRIVATE_KEY` (GitHub App)
to **both** Actions and Dependabot secret stores for the merge-bot.
- Let Dependabot bring `develop`'s deps up to match (or open a small
sync PR).
- Kick off the first publish via **Actions → publish-release.yml → Run
workflow** once secrets are in.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Convert to two-phase dual-publish release model - #320

Merged
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template
Jun 5, 2026
Merged

Convert to two-phase dual-publish release model#320
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Summary

Convert the project from publish-on-push to the ptr727/ProjectTemplatetwo-phase dual-publish release model, matching the structure already adopted by LanguageTags so future template changes apply as minimal deltas.

  • Phase 1 — PRs smoke-test only.test-pull-request.yml runs unit tests + a paths-filtered smoke build; merges no longer publish.
  • Phase 2 — weekly scheduled publish.publish-release.yml publishes both branches on a Monday 02:00 UTC cron and on manual dispatch, with idempotent no-op republish (skip release if the tag exists, --skip-duplicate on NuGet). Opt-in continuous-release via the PUBLISH_ON_MERGE repo variable.

Changes

  • Reusable workflow set: get-version-task, build-nugetlibrary-task, build-release-task, build-datebadge-task, plus publish-release, test-pull-request, and a branch-aware Dependabot merge-bot-pull-request (squash on develop / merge on main).
  • Removed BuildPublishPipeline.yml and DependabotAutoMerge.yml. NuGet.org-only (dropped the GitHub Packages push). No Docker/executable/PyPI/codegen targets.
  • Central Package Management (Directory.Build.props + Directory.Packages.props).
  • Added AGENTS.md documenting the branching/release/workflow conventions.
  • Reconciled the template's strict analyzers (AnalysisMode All + TreatWarningsAsErrors) with this brownfield library by relaxing specific rules in .editorconfig (each documented inline) and IL3058 via NoWarn; ImplicitUsings cleanup removed now-redundant usings.
  • Normalized line endings to .editorconfig and fixed the .husky/pre-commit shebang to LF + executable.

Maintainer follow-ups (not in this PR)

  • Add CODEGEN_APP_CLIENT_ID / CODEGEN_APP_PRIVATE_KEY (GitHub App) to both Actions and Dependabot secret stores for the merge-bot.
  • Bind the Check pull request workflow status required check to the develop (squash-only) and main (merge-only) rulesets.
  • Leave PUBLISH_ON_MERGE unset for the two-phase default.

🤖 Generated with Claude Code

ptr727 added 2 commits June 4, 2026 18:01
Replace publish-on-push with the ProjectTemplate/LanguageTags two-phase
model: PRs smoke-test only, and publish-release.yml publishes both branches
on a weekly schedule (Mon 02:00 UTC) or manual dispatch, with idempotent
no-op republish. Adopt the reusable workflow set (get-version,
build-nugetlibrary, build-release, build-datebadge), a branch-aware
Dependabot merge-bot, Central Package Management, and an AGENTS.md tracking
the template. NuGet.org-only (drop GitHub Packages); no Docker/exe/PyPI/codegen.
Reconcile the template's strict analyzers (AnalysisMode All +
TreatWarningsAsErrors) with the brownfield library by relaxing specific
rules in .editorconfig and IL3058 via NoWarn, all documented.
Convert the workflow YAML, dependabot.yml, and AGENTS.md (added LF) to CRLF
per .editorconfig, and make .husky/pre-commit LF + executable so its shebang
execs on Linux/WSL. Add an .editorconfig rule pinning the hook to LF.
CopilotAI review requested due to automatic review settings June 5, 2026 01:14

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

Migrates the repository’s CI/CD from the previous publish-on-push pipeline to the ProjectTemplate-aligned two-phase dual-publish model (PR smoke-test only; scheduled/manual publish of both main and develop), while introducing Central Package Management and codifying release/workflow conventions.

Changes:

  • Replaces the legacy build/publish workflows with a reusable-task workflow set, a PR-only test/smoke workflow, and a scheduled/manual publisher that can optionally publish on merge via PUBLISH_ON_MERGE.
  • Introduces Central Package Management (Directory.Build.props, Directory.Packages.props) and adjusts project files/using directives to rely on shared settings + implicit usings.
  • Adds/updates repo process documentation and configuration (AGENTS.md, .editorconfig, hook shebang/line-endings, .gitignore, README badge).

Reviewed changes

Copilot reviewed 38 out of 40 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
UtilitiesTests/UtilitiesTests.csprojRemoves per-project TFM/analyzer/version pinning to rely on shared build props + central package versions.
UtilitiesTests/UtilitiesTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringHistoryTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/FileExAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ExtensionsTests.csUpdates null-argument extension tests and removes redundant usings as part of analyzer/implicit-using cleanup.
UtilitiesTests/DownloadTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/DownloadAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ConsoleTests.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Utilities.csprojMoves analyzer/TFM/nullable to shared props; adds AOT warning suppression for IL3058; uses CPM.
Utilities/StringHistory.csRemoves redundant explicit using now covered by implicit usings.
Utilities/StringCompression.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Format.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileExOptions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Extensions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Download.csRemoves redundant explicit using now covered by implicit usings.
Utilities/ConsoleEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/CommandLineEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities.slnxAdds new solution items for CPM + agent/process docs + new workflows; removes legacy workflow entries.
Sandbox/Sandbox.csprojAligns sandbox build props with shared settings + CPM; suppresses IL3058 similarly.
Sandbox/Program.csMinor cleanup to use AppContext and rely on implicit usings.
README.mdUpdates workflow-status badge to point at the new publisher workflow.
Directory.Packages.propsAdds central package version definitions for NuGet, tests, and Serilog dependencies.
Directory.Build.propsAdds shared build settings (TFM, analyzers, WarningsAsErrors, artifacts path, CPM enablement).
AGENTS.mdDocuments branching rules, release model, and workflow conventions for maintainers/agents.
.husky/pre-commitNormalizes shebang/line-endings to ensure hook runs on POSIX shells.
.gitignoreIgnores .artifacts folder produced by the shared ArtifactsPath.
.github/workflows/test-pull-request.ymlNew PR workflow: unit tests + paths-filter-gated smoke build + required-status aggregator job.
.github/workflows/publish-release.ymlNew publisher: scheduled/manual dual-branch publish, optional push-publish gated by PUBLISH_ON_MERGE.
.github/workflows/merge-bot-pull-request.ymlNew Dependabot merge-bot using App token and branch-aware merge method.
.github/workflows/get-version-task.ymlNew reusable workflow to compute NBGV version metadata with a pinned checkout ref.
.github/workflows/build-release-task.ymlNew reusable orchestrator tying versioning, NuGet build/push, and GitHub release creation together.
.github/workflows/build-nugetlibrary-task.ymlNew reusable NuGet build/push + artifact upload task, branch-config aware.
.github/workflows/build-datebadge-task.ymlNew reusable BYOB badge task gated to main.
.github/workflows/DependabotAutoMerge.ymlRemoves legacy Dependabot auto-merge workflow in favor of merge-bot model.
.github/workflows/BuildPublishPipeline.ymlRemoves legacy publish-on-push pipeline in favor of two-phase model.
.github/dependabot.ymlUpdates Dependabot config to open updates against both main and develop.
.editorconfigAdds LF override for husky hook + documents analyzer relaxations for brownfield code under strict analysis mode.

Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment thread.github/workflows/build-datebadge-task.yml
@ptr727
ptr727 merged commit 0e65bd2 into developJun 5, 2026
7 checks passed
@ptr727
ptr727 deleted the convert-dualpublish-template branch June 5, 2026 01:28
ptr727 added a commit that referenced this pull request Jun 5, 2026
## Summary
Land the two-phase dual-publish model on `main`, with **fully signed &
GitHub-verified history**. This is `main` merged with `develop`
(`0f1616d`), the one-time old→new structural conflicts resolved in
**develop's favour**, and the **max dependency/tool versions** taken so
`main`'s newer Dependabot bumps are not regressed.
All introduced commits are committer = `Pieter Viljoen
<ptr727@users.noreply.github.com>` and verified, satisfying
`required_signatures` (supersedes #322/#323, which carried unverifiable
web-flow-committed history).
### Dependency reconciliation (max of develop/main)
| Package / tool | Version |
| --- | --- |
| Microsoft.SourceLink.GitHub | 10.0.201 |
| Serilog | 4.3.1 |
| Microsoft.NET.Test.Sdk | 18.4.0 |
| xunit.analyzers | 1.27.0 |
| csharpier (tool) | 1.2.6 |
| husky (tool) | 0.9.1 |
Net diff vs `develop` is only the six version bumps above. See #320 for
the full change description.
## Maintainer follow-ups (after merge)
- Add `CODEGEN_APP_CLIENT_ID` / `CODEGEN_APP_PRIVATE_KEY` (GitHub App)
to **both** Actions and Dependabot secret stores for the merge-bot.
- Let Dependabot bring `develop`'s deps up to match (or open a small
sync PR).
- Kick off the first publish via **Actions → publish-release.yml → Run
workflow** once secrets are in.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Convert to two-phase dual-publish release model - #320

Merged
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template
Jun 5, 2026
Merged

Convert to two-phase dual-publish release model#320
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Summary

Convert the project from publish-on-push to the ptr727/ProjectTemplatetwo-phase dual-publish release model, matching the structure already adopted by LanguageTags so future template changes apply as minimal deltas.

  • Phase 1 — PRs smoke-test only.test-pull-request.yml runs unit tests + a paths-filtered smoke build; merges no longer publish.
  • Phase 2 — weekly scheduled publish.publish-release.yml publishes both branches on a Monday 02:00 UTC cron and on manual dispatch, with idempotent no-op republish (skip release if the tag exists, --skip-duplicate on NuGet). Opt-in continuous-release via the PUBLISH_ON_MERGE repo variable.

Changes

  • Reusable workflow set: get-version-task, build-nugetlibrary-task, build-release-task, build-datebadge-task, plus publish-release, test-pull-request, and a branch-aware Dependabot merge-bot-pull-request (squash on develop / merge on main).
  • Removed BuildPublishPipeline.yml and DependabotAutoMerge.yml. NuGet.org-only (dropped the GitHub Packages push). No Docker/executable/PyPI/codegen targets.
  • Central Package Management (Directory.Build.props + Directory.Packages.props).
  • Added AGENTS.md documenting the branching/release/workflow conventions.
  • Reconciled the template's strict analyzers (AnalysisMode All + TreatWarningsAsErrors) with this brownfield library by relaxing specific rules in .editorconfig (each documented inline) and IL3058 via NoWarn; ImplicitUsings cleanup removed now-redundant usings.
  • Normalized line endings to .editorconfig and fixed the .husky/pre-commit shebang to LF + executable.

Maintainer follow-ups (not in this PR)

  • Add CODEGEN_APP_CLIENT_ID / CODEGEN_APP_PRIVATE_KEY (GitHub App) to both Actions and Dependabot secret stores for the merge-bot.
  • Bind the Check pull request workflow status required check to the develop (squash-only) and main (merge-only) rulesets.
  • Leave PUBLISH_ON_MERGE unset for the two-phase default.

🤖 Generated with Claude Code

ptr727 added 2 commits June 4, 2026 18:01
Replace publish-on-push with the ProjectTemplate/LanguageTags two-phase
model: PRs smoke-test only, and publish-release.yml publishes both branches
on a weekly schedule (Mon 02:00 UTC) or manual dispatch, with idempotent
no-op republish. Adopt the reusable workflow set (get-version,
build-nugetlibrary, build-release, build-datebadge), a branch-aware
Dependabot merge-bot, Central Package Management, and an AGENTS.md tracking
the template. NuGet.org-only (drop GitHub Packages); no Docker/exe/PyPI/codegen.
Reconcile the template's strict analyzers (AnalysisMode All +
TreatWarningsAsErrors) with the brownfield library by relaxing specific
rules in .editorconfig and IL3058 via NoWarn, all documented.
Convert the workflow YAML, dependabot.yml, and AGENTS.md (added LF) to CRLF
per .editorconfig, and make .husky/pre-commit LF + executable so its shebang
execs on Linux/WSL. Add an .editorconfig rule pinning the hook to LF.
CopilotAI review requested due to automatic review settings June 5, 2026 01:14

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

Migrates the repository’s CI/CD from the previous publish-on-push pipeline to the ProjectTemplate-aligned two-phase dual-publish model (PR smoke-test only; scheduled/manual publish of both main and develop), while introducing Central Package Management and codifying release/workflow conventions.

Changes:

  • Replaces the legacy build/publish workflows with a reusable-task workflow set, a PR-only test/smoke workflow, and a scheduled/manual publisher that can optionally publish on merge via PUBLISH_ON_MERGE.
  • Introduces Central Package Management (Directory.Build.props, Directory.Packages.props) and adjusts project files/using directives to rely on shared settings + implicit usings.
  • Adds/updates repo process documentation and configuration (AGENTS.md, .editorconfig, hook shebang/line-endings, .gitignore, README badge).

Reviewed changes

Copilot reviewed 38 out of 40 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
UtilitiesTests/UtilitiesTests.csprojRemoves per-project TFM/analyzer/version pinning to rely on shared build props + central package versions.
UtilitiesTests/UtilitiesTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringHistoryTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/FileExAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ExtensionsTests.csUpdates null-argument extension tests and removes redundant usings as part of analyzer/implicit-using cleanup.
UtilitiesTests/DownloadTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/DownloadAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ConsoleTests.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Utilities.csprojMoves analyzer/TFM/nullable to shared props; adds AOT warning suppression for IL3058; uses CPM.
Utilities/StringHistory.csRemoves redundant explicit using now covered by implicit usings.
Utilities/StringCompression.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Format.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileExOptions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Extensions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Download.csRemoves redundant explicit using now covered by implicit usings.
Utilities/ConsoleEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/CommandLineEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities.slnxAdds new solution items for CPM + agent/process docs + new workflows; removes legacy workflow entries.
Sandbox/Sandbox.csprojAligns sandbox build props with shared settings + CPM; suppresses IL3058 similarly.
Sandbox/Program.csMinor cleanup to use AppContext and rely on implicit usings.
README.mdUpdates workflow-status badge to point at the new publisher workflow.
Directory.Packages.propsAdds central package version definitions for NuGet, tests, and Serilog dependencies.
Directory.Build.propsAdds shared build settings (TFM, analyzers, WarningsAsErrors, artifacts path, CPM enablement).
AGENTS.mdDocuments branching rules, release model, and workflow conventions for maintainers/agents.
.husky/pre-commitNormalizes shebang/line-endings to ensure hook runs on POSIX shells.
.gitignoreIgnores .artifacts folder produced by the shared ArtifactsPath.
.github/workflows/test-pull-request.ymlNew PR workflow: unit tests + paths-filter-gated smoke build + required-status aggregator job.
.github/workflows/publish-release.ymlNew publisher: scheduled/manual dual-branch publish, optional push-publish gated by PUBLISH_ON_MERGE.
.github/workflows/merge-bot-pull-request.ymlNew Dependabot merge-bot using App token and branch-aware merge method.
.github/workflows/get-version-task.ymlNew reusable workflow to compute NBGV version metadata with a pinned checkout ref.
.github/workflows/build-release-task.ymlNew reusable orchestrator tying versioning, NuGet build/push, and GitHub release creation together.
.github/workflows/build-nugetlibrary-task.ymlNew reusable NuGet build/push + artifact upload task, branch-config aware.
.github/workflows/build-datebadge-task.ymlNew reusable BYOB badge task gated to main.
.github/workflows/DependabotAutoMerge.ymlRemoves legacy Dependabot auto-merge workflow in favor of merge-bot model.
.github/workflows/BuildPublishPipeline.ymlRemoves legacy publish-on-push pipeline in favor of two-phase model.
.github/dependabot.ymlUpdates Dependabot config to open updates against both main and develop.
.editorconfigAdds LF override for husky hook + documents analyzer relaxations for brownfield code under strict analysis mode.

Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment thread.github/workflows/build-datebadge-task.yml
@ptr727
ptr727 merged commit 0e65bd2 into developJun 5, 2026
7 checks passed
@ptr727
ptr727 deleted the convert-dualpublish-template branch June 5, 2026 01:28
ptr727 added a commit that referenced this pull request Jun 5, 2026
## Summary
Land the two-phase dual-publish model on `main`, with **fully signed &
GitHub-verified history**. This is `main` merged with `develop`
(`0f1616d`), the one-time old→new structural conflicts resolved in
**develop's favour**, and the **max dependency/tool versions** taken so
`main`'s newer Dependabot bumps are not regressed.
All introduced commits are committer = `Pieter Viljoen
<ptr727@users.noreply.github.com>` and verified, satisfying
`required_signatures` (supersedes #322/#323, which carried unverifiable
web-flow-committed history).
### Dependency reconciliation (max of develop/main)
| Package / tool | Version |
| --- | --- |
| Microsoft.SourceLink.GitHub | 10.0.201 |
| Serilog | 4.3.1 |
| Microsoft.NET.Test.Sdk | 18.4.0 |
| xunit.analyzers | 1.27.0 |
| csharpier (tool) | 1.2.6 |
| husky (tool) | 0.9.1 |
Net diff vs `develop` is only the six version bumps above. See #320 for
the full change description.
## Maintainer follow-ups (after merge)
- Add `CODEGEN_APP_CLIENT_ID` / `CODEGEN_APP_PRIVATE_KEY` (GitHub App)
to **both** Actions and Dependabot secret stores for the merge-bot.
- Let Dependabot bring `develop`'s deps up to match (or open a small
sync PR).
- Kick off the first publish via **Actions → publish-release.yml → Run
workflow** once secrets are in.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Convert to two-phase dual-publish release model - #320

Merged
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template
Jun 5, 2026
Merged

Convert to two-phase dual-publish release model#320
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Summary

Convert the project from publish-on-push to the ptr727/ProjectTemplatetwo-phase dual-publish release model, matching the structure already adopted by LanguageTags so future template changes apply as minimal deltas.

  • Phase 1 — PRs smoke-test only.test-pull-request.yml runs unit tests + a paths-filtered smoke build; merges no longer publish.
  • Phase 2 — weekly scheduled publish.publish-release.yml publishes both branches on a Monday 02:00 UTC cron and on manual dispatch, with idempotent no-op republish (skip release if the tag exists, --skip-duplicate on NuGet). Opt-in continuous-release via the PUBLISH_ON_MERGE repo variable.

Changes

  • Reusable workflow set: get-version-task, build-nugetlibrary-task, build-release-task, build-datebadge-task, plus publish-release, test-pull-request, and a branch-aware Dependabot merge-bot-pull-request (squash on develop / merge on main).
  • Removed BuildPublishPipeline.yml and DependabotAutoMerge.yml. NuGet.org-only (dropped the GitHub Packages push). No Docker/executable/PyPI/codegen targets.
  • Central Package Management (Directory.Build.props + Directory.Packages.props).
  • Added AGENTS.md documenting the branching/release/workflow conventions.
  • Reconciled the template's strict analyzers (AnalysisMode All + TreatWarningsAsErrors) with this brownfield library by relaxing specific rules in .editorconfig (each documented inline) and IL3058 via NoWarn; ImplicitUsings cleanup removed now-redundant usings.
  • Normalized line endings to .editorconfig and fixed the .husky/pre-commit shebang to LF + executable.

Maintainer follow-ups (not in this PR)

  • Add CODEGEN_APP_CLIENT_ID / CODEGEN_APP_PRIVATE_KEY (GitHub App) to both Actions and Dependabot secret stores for the merge-bot.
  • Bind the Check pull request workflow status required check to the develop (squash-only) and main (merge-only) rulesets.
  • Leave PUBLISH_ON_MERGE unset for the two-phase default.

🤖 Generated with Claude Code

ptr727 added 2 commits June 4, 2026 18:01
Replace publish-on-push with the ProjectTemplate/LanguageTags two-phase
model: PRs smoke-test only, and publish-release.yml publishes both branches
on a weekly schedule (Mon 02:00 UTC) or manual dispatch, with idempotent
no-op republish. Adopt the reusable workflow set (get-version,
build-nugetlibrary, build-release, build-datebadge), a branch-aware
Dependabot merge-bot, Central Package Management, and an AGENTS.md tracking
the template. NuGet.org-only (drop GitHub Packages); no Docker/exe/PyPI/codegen.
Reconcile the template's strict analyzers (AnalysisMode All +
TreatWarningsAsErrors) with the brownfield library by relaxing specific
rules in .editorconfig and IL3058 via NoWarn, all documented.
Convert the workflow YAML, dependabot.yml, and AGENTS.md (added LF) to CRLF
per .editorconfig, and make .husky/pre-commit LF + executable so its shebang
execs on Linux/WSL. Add an .editorconfig rule pinning the hook to LF.
CopilotAI review requested due to automatic review settings June 5, 2026 01:14

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

Migrates the repository’s CI/CD from the previous publish-on-push pipeline to the ProjectTemplate-aligned two-phase dual-publish model (PR smoke-test only; scheduled/manual publish of both main and develop), while introducing Central Package Management and codifying release/workflow conventions.

Changes:

  • Replaces the legacy build/publish workflows with a reusable-task workflow set, a PR-only test/smoke workflow, and a scheduled/manual publisher that can optionally publish on merge via PUBLISH_ON_MERGE.
  • Introduces Central Package Management (Directory.Build.props, Directory.Packages.props) and adjusts project files/using directives to rely on shared settings + implicit usings.
  • Adds/updates repo process documentation and configuration (AGENTS.md, .editorconfig, hook shebang/line-endings, .gitignore, README badge).

Reviewed changes

Copilot reviewed 38 out of 40 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
UtilitiesTests/UtilitiesTests.csprojRemoves per-project TFM/analyzer/version pinning to rely on shared build props + central package versions.
UtilitiesTests/UtilitiesTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringHistoryTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/FileExAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ExtensionsTests.csUpdates null-argument extension tests and removes redundant usings as part of analyzer/implicit-using cleanup.
UtilitiesTests/DownloadTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/DownloadAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ConsoleTests.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Utilities.csprojMoves analyzer/TFM/nullable to shared props; adds AOT warning suppression for IL3058; uses CPM.
Utilities/StringHistory.csRemoves redundant explicit using now covered by implicit usings.
Utilities/StringCompression.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Format.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileExOptions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Extensions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Download.csRemoves redundant explicit using now covered by implicit usings.
Utilities/ConsoleEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/CommandLineEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities.slnxAdds new solution items for CPM + agent/process docs + new workflows; removes legacy workflow entries.
Sandbox/Sandbox.csprojAligns sandbox build props with shared settings + CPM; suppresses IL3058 similarly.
Sandbox/Program.csMinor cleanup to use AppContext and rely on implicit usings.
README.mdUpdates workflow-status badge to point at the new publisher workflow.
Directory.Packages.propsAdds central package version definitions for NuGet, tests, and Serilog dependencies.
Directory.Build.propsAdds shared build settings (TFM, analyzers, WarningsAsErrors, artifacts path, CPM enablement).
AGENTS.mdDocuments branching rules, release model, and workflow conventions for maintainers/agents.
.husky/pre-commitNormalizes shebang/line-endings to ensure hook runs on POSIX shells.
.gitignoreIgnores .artifacts folder produced by the shared ArtifactsPath.
.github/workflows/test-pull-request.ymlNew PR workflow: unit tests + paths-filter-gated smoke build + required-status aggregator job.
.github/workflows/publish-release.ymlNew publisher: scheduled/manual dual-branch publish, optional push-publish gated by PUBLISH_ON_MERGE.
.github/workflows/merge-bot-pull-request.ymlNew Dependabot merge-bot using App token and branch-aware merge method.
.github/workflows/get-version-task.ymlNew reusable workflow to compute NBGV version metadata with a pinned checkout ref.
.github/workflows/build-release-task.ymlNew reusable orchestrator tying versioning, NuGet build/push, and GitHub release creation together.
.github/workflows/build-nugetlibrary-task.ymlNew reusable NuGet build/push + artifact upload task, branch-config aware.
.github/workflows/build-datebadge-task.ymlNew reusable BYOB badge task gated to main.
.github/workflows/DependabotAutoMerge.ymlRemoves legacy Dependabot auto-merge workflow in favor of merge-bot model.
.github/workflows/BuildPublishPipeline.ymlRemoves legacy publish-on-push pipeline in favor of two-phase model.
.github/dependabot.ymlUpdates Dependabot config to open updates against both main and develop.
.editorconfigAdds LF override for husky hook + documents analyzer relaxations for brownfield code under strict analysis mode.

Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment thread.github/workflows/build-datebadge-task.yml
@ptr727
ptr727 merged commit 0e65bd2 into developJun 5, 2026
7 checks passed
@ptr727
ptr727 deleted the convert-dualpublish-template branch June 5, 2026 01:28
ptr727 added a commit that referenced this pull request Jun 5, 2026
## Summary
Land the two-phase dual-publish model on `main`, with **fully signed &
GitHub-verified history**. This is `main` merged with `develop`
(`0f1616d`), the one-time old→new structural conflicts resolved in
**develop's favour**, and the **max dependency/tool versions** taken so
`main`'s newer Dependabot bumps are not regressed.
All introduced commits are committer = `Pieter Viljoen
<ptr727@users.noreply.github.com>` and verified, satisfying
`required_signatures` (supersedes #322/#323, which carried unverifiable
web-flow-committed history).
### Dependency reconciliation (max of develop/main)
| Package / tool | Version |
| --- | --- |
| Microsoft.SourceLink.GitHub | 10.0.201 |
| Serilog | 4.3.1 |
| Microsoft.NET.Test.Sdk | 18.4.0 |
| xunit.analyzers | 1.27.0 |
| csharpier (tool) | 1.2.6 |
| husky (tool) | 0.9.1 |
Net diff vs `develop` is only the six version bumps above. See #320 for
the full change description.
## Maintainer follow-ups (after merge)
- Add `CODEGEN_APP_CLIENT_ID` / `CODEGEN_APP_PRIVATE_KEY` (GitHub App)
to **both** Actions and Dependabot secret stores for the merge-bot.
- Let Dependabot bring `develop`'s deps up to match (or open a small
sync PR).
- Kick off the first publish via **Actions → publish-release.yml → Run
workflow** once secrets are in.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Convert to two-phase dual-publish release model - #320

Merged
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template
Jun 5, 2026
Merged

Convert to two-phase dual-publish release model#320
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Summary

Convert the project from publish-on-push to the ptr727/ProjectTemplatetwo-phase dual-publish release model, matching the structure already adopted by LanguageTags so future template changes apply as minimal deltas.

  • Phase 1 — PRs smoke-test only.test-pull-request.yml runs unit tests + a paths-filtered smoke build; merges no longer publish.
  • Phase 2 — weekly scheduled publish.publish-release.yml publishes both branches on a Monday 02:00 UTC cron and on manual dispatch, with idempotent no-op republish (skip release if the tag exists, --skip-duplicate on NuGet). Opt-in continuous-release via the PUBLISH_ON_MERGE repo variable.

Changes

  • Reusable workflow set: get-version-task, build-nugetlibrary-task, build-release-task, build-datebadge-task, plus publish-release, test-pull-request, and a branch-aware Dependabot merge-bot-pull-request (squash on develop / merge on main).
  • Removed BuildPublishPipeline.yml and DependabotAutoMerge.yml. NuGet.org-only (dropped the GitHub Packages push). No Docker/executable/PyPI/codegen targets.
  • Central Package Management (Directory.Build.props + Directory.Packages.props).
  • Added AGENTS.md documenting the branching/release/workflow conventions.
  • Reconciled the template's strict analyzers (AnalysisMode All + TreatWarningsAsErrors) with this brownfield library by relaxing specific rules in .editorconfig (each documented inline) and IL3058 via NoWarn; ImplicitUsings cleanup removed now-redundant usings.
  • Normalized line endings to .editorconfig and fixed the .husky/pre-commit shebang to LF + executable.

Maintainer follow-ups (not in this PR)

  • Add CODEGEN_APP_CLIENT_ID / CODEGEN_APP_PRIVATE_KEY (GitHub App) to both Actions and Dependabot secret stores for the merge-bot.
  • Bind the Check pull request workflow status required check to the develop (squash-only) and main (merge-only) rulesets.
  • Leave PUBLISH_ON_MERGE unset for the two-phase default.

🤖 Generated with Claude Code

ptr727 added 2 commits June 4, 2026 18:01
Replace publish-on-push with the ProjectTemplate/LanguageTags two-phase
model: PRs smoke-test only, and publish-release.yml publishes both branches
on a weekly schedule (Mon 02:00 UTC) or manual dispatch, with idempotent
no-op republish. Adopt the reusable workflow set (get-version,
build-nugetlibrary, build-release, build-datebadge), a branch-aware
Dependabot merge-bot, Central Package Management, and an AGENTS.md tracking
the template. NuGet.org-only (drop GitHub Packages); no Docker/exe/PyPI/codegen.
Reconcile the template's strict analyzers (AnalysisMode All +
TreatWarningsAsErrors) with the brownfield library by relaxing specific
rules in .editorconfig and IL3058 via NoWarn, all documented.
Convert the workflow YAML, dependabot.yml, and AGENTS.md (added LF) to CRLF
per .editorconfig, and make .husky/pre-commit LF + executable so its shebang
execs on Linux/WSL. Add an .editorconfig rule pinning the hook to LF.
CopilotAI review requested due to automatic review settings June 5, 2026 01:14

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

Migrates the repository’s CI/CD from the previous publish-on-push pipeline to the ProjectTemplate-aligned two-phase dual-publish model (PR smoke-test only; scheduled/manual publish of both main and develop), while introducing Central Package Management and codifying release/workflow conventions.

Changes:

  • Replaces the legacy build/publish workflows with a reusable-task workflow set, a PR-only test/smoke workflow, and a scheduled/manual publisher that can optionally publish on merge via PUBLISH_ON_MERGE.
  • Introduces Central Package Management (Directory.Build.props, Directory.Packages.props) and adjusts project files/using directives to rely on shared settings + implicit usings.
  • Adds/updates repo process documentation and configuration (AGENTS.md, .editorconfig, hook shebang/line-endings, .gitignore, README badge).

Reviewed changes

Copilot reviewed 38 out of 40 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
UtilitiesTests/UtilitiesTests.csprojRemoves per-project TFM/analyzer/version pinning to rely on shared build props + central package versions.
UtilitiesTests/UtilitiesTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringHistoryTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/FileExAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ExtensionsTests.csUpdates null-argument extension tests and removes redundant usings as part of analyzer/implicit-using cleanup.
UtilitiesTests/DownloadTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/DownloadAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ConsoleTests.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Utilities.csprojMoves analyzer/TFM/nullable to shared props; adds AOT warning suppression for IL3058; uses CPM.
Utilities/StringHistory.csRemoves redundant explicit using now covered by implicit usings.
Utilities/StringCompression.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Format.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileExOptions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Extensions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Download.csRemoves redundant explicit using now covered by implicit usings.
Utilities/ConsoleEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/CommandLineEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities.slnxAdds new solution items for CPM + agent/process docs + new workflows; removes legacy workflow entries.
Sandbox/Sandbox.csprojAligns sandbox build props with shared settings + CPM; suppresses IL3058 similarly.
Sandbox/Program.csMinor cleanup to use AppContext and rely on implicit usings.
README.mdUpdates workflow-status badge to point at the new publisher workflow.
Directory.Packages.propsAdds central package version definitions for NuGet, tests, and Serilog dependencies.
Directory.Build.propsAdds shared build settings (TFM, analyzers, WarningsAsErrors, artifacts path, CPM enablement).
AGENTS.mdDocuments branching rules, release model, and workflow conventions for maintainers/agents.
.husky/pre-commitNormalizes shebang/line-endings to ensure hook runs on POSIX shells.
.gitignoreIgnores .artifacts folder produced by the shared ArtifactsPath.
.github/workflows/test-pull-request.ymlNew PR workflow: unit tests + paths-filter-gated smoke build + required-status aggregator job.
.github/workflows/publish-release.ymlNew publisher: scheduled/manual dual-branch publish, optional push-publish gated by PUBLISH_ON_MERGE.
.github/workflows/merge-bot-pull-request.ymlNew Dependabot merge-bot using App token and branch-aware merge method.
.github/workflows/get-version-task.ymlNew reusable workflow to compute NBGV version metadata with a pinned checkout ref.
.github/workflows/build-release-task.ymlNew reusable orchestrator tying versioning, NuGet build/push, and GitHub release creation together.
.github/workflows/build-nugetlibrary-task.ymlNew reusable NuGet build/push + artifact upload task, branch-config aware.
.github/workflows/build-datebadge-task.ymlNew reusable BYOB badge task gated to main.
.github/workflows/DependabotAutoMerge.ymlRemoves legacy Dependabot auto-merge workflow in favor of merge-bot model.
.github/workflows/BuildPublishPipeline.ymlRemoves legacy publish-on-push pipeline in favor of two-phase model.
.github/dependabot.ymlUpdates Dependabot config to open updates against both main and develop.
.editorconfigAdds LF override for husky hook + documents analyzer relaxations for brownfield code under strict analysis mode.

Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment thread.github/workflows/build-datebadge-task.yml
@ptr727
ptr727 merged commit 0e65bd2 into developJun 5, 2026
7 checks passed
@ptr727
ptr727 deleted the convert-dualpublish-template branch June 5, 2026 01:28
ptr727 added a commit that referenced this pull request Jun 5, 2026
## Summary
Land the two-phase dual-publish model on `main`, with **fully signed &
GitHub-verified history**. This is `main` merged with `develop`
(`0f1616d`), the one-time old→new structural conflicts resolved in
**develop's favour**, and the **max dependency/tool versions** taken so
`main`'s newer Dependabot bumps are not regressed.
All introduced commits are committer = `Pieter Viljoen
<ptr727@users.noreply.github.com>` and verified, satisfying
`required_signatures` (supersedes #322/#323, which carried unverifiable
web-flow-committed history).
### Dependency reconciliation (max of develop/main)
| Package / tool | Version |
| --- | --- |
| Microsoft.SourceLink.GitHub | 10.0.201 |
| Serilog | 4.3.1 |
| Microsoft.NET.Test.Sdk | 18.4.0 |
| xunit.analyzers | 1.27.0 |
| csharpier (tool) | 1.2.6 |
| husky (tool) | 0.9.1 |
Net diff vs `develop` is only the six version bumps above. See #320 for
the full change description.
## Maintainer follow-ups (after merge)
- Add `CODEGEN_APP_CLIENT_ID` / `CODEGEN_APP_PRIVATE_KEY` (GitHub App)
to **both** Actions and Dependabot secret stores for the merge-bot.
- Let Dependabot bring `develop`'s deps up to match (or open a small
sync PR).
- Kick off the first publish via **Actions → publish-release.yml → Run
workflow** once secrets are in.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Convert to two-phase dual-publish release model - #320

Merged
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template
Jun 5, 2026
Merged

Convert to two-phase dual-publish release model#320
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Summary

Convert the project from publish-on-push to the ptr727/ProjectTemplatetwo-phase dual-publish release model, matching the structure already adopted by LanguageTags so future template changes apply as minimal deltas.

  • Phase 1 — PRs smoke-test only.test-pull-request.yml runs unit tests + a paths-filtered smoke build; merges no longer publish.
  • Phase 2 — weekly scheduled publish.publish-release.yml publishes both branches on a Monday 02:00 UTC cron and on manual dispatch, with idempotent no-op republish (skip release if the tag exists, --skip-duplicate on NuGet). Opt-in continuous-release via the PUBLISH_ON_MERGE repo variable.

Changes

  • Reusable workflow set: get-version-task, build-nugetlibrary-task, build-release-task, build-datebadge-task, plus publish-release, test-pull-request, and a branch-aware Dependabot merge-bot-pull-request (squash on develop / merge on main).
  • Removed BuildPublishPipeline.yml and DependabotAutoMerge.yml. NuGet.org-only (dropped the GitHub Packages push). No Docker/executable/PyPI/codegen targets.
  • Central Package Management (Directory.Build.props + Directory.Packages.props).
  • Added AGENTS.md documenting the branching/release/workflow conventions.
  • Reconciled the template's strict analyzers (AnalysisMode All + TreatWarningsAsErrors) with this brownfield library by relaxing specific rules in .editorconfig (each documented inline) and IL3058 via NoWarn; ImplicitUsings cleanup removed now-redundant usings.
  • Normalized line endings to .editorconfig and fixed the .husky/pre-commit shebang to LF + executable.

Maintainer follow-ups (not in this PR)

  • Add CODEGEN_APP_CLIENT_ID / CODEGEN_APP_PRIVATE_KEY (GitHub App) to both Actions and Dependabot secret stores for the merge-bot.
  • Bind the Check pull request workflow status required check to the develop (squash-only) and main (merge-only) rulesets.
  • Leave PUBLISH_ON_MERGE unset for the two-phase default.

🤖 Generated with Claude Code

ptr727 added 2 commits June 4, 2026 18:01
Replace publish-on-push with the ProjectTemplate/LanguageTags two-phase
model: PRs smoke-test only, and publish-release.yml publishes both branches
on a weekly schedule (Mon 02:00 UTC) or manual dispatch, with idempotent
no-op republish. Adopt the reusable workflow set (get-version,
build-nugetlibrary, build-release, build-datebadge), a branch-aware
Dependabot merge-bot, Central Package Management, and an AGENTS.md tracking
the template. NuGet.org-only (drop GitHub Packages); no Docker/exe/PyPI/codegen.
Reconcile the template's strict analyzers (AnalysisMode All +
TreatWarningsAsErrors) with the brownfield library by relaxing specific
rules in .editorconfig and IL3058 via NoWarn, all documented.
Convert the workflow YAML, dependabot.yml, and AGENTS.md (added LF) to CRLF
per .editorconfig, and make .husky/pre-commit LF + executable so its shebang
execs on Linux/WSL. Add an .editorconfig rule pinning the hook to LF.
CopilotAI review requested due to automatic review settings June 5, 2026 01:14

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

Migrates the repository’s CI/CD from the previous publish-on-push pipeline to the ProjectTemplate-aligned two-phase dual-publish model (PR smoke-test only; scheduled/manual publish of both main and develop), while introducing Central Package Management and codifying release/workflow conventions.

Changes:

  • Replaces the legacy build/publish workflows with a reusable-task workflow set, a PR-only test/smoke workflow, and a scheduled/manual publisher that can optionally publish on merge via PUBLISH_ON_MERGE.
  • Introduces Central Package Management (Directory.Build.props, Directory.Packages.props) and adjusts project files/using directives to rely on shared settings + implicit usings.
  • Adds/updates repo process documentation and configuration (AGENTS.md, .editorconfig, hook shebang/line-endings, .gitignore, README badge).

Reviewed changes

Copilot reviewed 38 out of 40 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
UtilitiesTests/UtilitiesTests.csprojRemoves per-project TFM/analyzer/version pinning to rely on shared build props + central package versions.
UtilitiesTests/UtilitiesTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringHistoryTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/FileExAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ExtensionsTests.csUpdates null-argument extension tests and removes redundant usings as part of analyzer/implicit-using cleanup.
UtilitiesTests/DownloadTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/DownloadAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ConsoleTests.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Utilities.csprojMoves analyzer/TFM/nullable to shared props; adds AOT warning suppression for IL3058; uses CPM.
Utilities/StringHistory.csRemoves redundant explicit using now covered by implicit usings.
Utilities/StringCompression.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Format.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileExOptions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Extensions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Download.csRemoves redundant explicit using now covered by implicit usings.
Utilities/ConsoleEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/CommandLineEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities.slnxAdds new solution items for CPM + agent/process docs + new workflows; removes legacy workflow entries.
Sandbox/Sandbox.csprojAligns sandbox build props with shared settings + CPM; suppresses IL3058 similarly.
Sandbox/Program.csMinor cleanup to use AppContext and rely on implicit usings.
README.mdUpdates workflow-status badge to point at the new publisher workflow.
Directory.Packages.propsAdds central package version definitions for NuGet, tests, and Serilog dependencies.
Directory.Build.propsAdds shared build settings (TFM, analyzers, WarningsAsErrors, artifacts path, CPM enablement).
AGENTS.mdDocuments branching rules, release model, and workflow conventions for maintainers/agents.
.husky/pre-commitNormalizes shebang/line-endings to ensure hook runs on POSIX shells.
.gitignoreIgnores .artifacts folder produced by the shared ArtifactsPath.
.github/workflows/test-pull-request.ymlNew PR workflow: unit tests + paths-filter-gated smoke build + required-status aggregator job.
.github/workflows/publish-release.ymlNew publisher: scheduled/manual dual-branch publish, optional push-publish gated by PUBLISH_ON_MERGE.
.github/workflows/merge-bot-pull-request.ymlNew Dependabot merge-bot using App token and branch-aware merge method.
.github/workflows/get-version-task.ymlNew reusable workflow to compute NBGV version metadata with a pinned checkout ref.
.github/workflows/build-release-task.ymlNew reusable orchestrator tying versioning, NuGet build/push, and GitHub release creation together.
.github/workflows/build-nugetlibrary-task.ymlNew reusable NuGet build/push + artifact upload task, branch-config aware.
.github/workflows/build-datebadge-task.ymlNew reusable BYOB badge task gated to main.
.github/workflows/DependabotAutoMerge.ymlRemoves legacy Dependabot auto-merge workflow in favor of merge-bot model.
.github/workflows/BuildPublishPipeline.ymlRemoves legacy publish-on-push pipeline in favor of two-phase model.
.github/dependabot.ymlUpdates Dependabot config to open updates against both main and develop.
.editorconfigAdds LF override for husky hook + documents analyzer relaxations for brownfield code under strict analysis mode.

Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment thread.github/workflows/build-datebadge-task.yml
@ptr727
ptr727 merged commit 0e65bd2 into developJun 5, 2026
7 checks passed
@ptr727
ptr727 deleted the convert-dualpublish-template branch June 5, 2026 01:28
ptr727 added a commit that referenced this pull request Jun 5, 2026
## Summary
Land the two-phase dual-publish model on `main`, with **fully signed &
GitHub-verified history**. This is `main` merged with `develop`
(`0f1616d`), the one-time old→new structural conflicts resolved in
**develop's favour**, and the **max dependency/tool versions** taken so
`main`'s newer Dependabot bumps are not regressed.
All introduced commits are committer = `Pieter Viljoen
<ptr727@users.noreply.github.com>` and verified, satisfying
`required_signatures` (supersedes #322/#323, which carried unverifiable
web-flow-committed history).
### Dependency reconciliation (max of develop/main)
| Package / tool | Version |
| --- | --- |
| Microsoft.SourceLink.GitHub | 10.0.201 |
| Serilog | 4.3.1 |
| Microsoft.NET.Test.Sdk | 18.4.0 |
| xunit.analyzers | 1.27.0 |
| csharpier (tool) | 1.2.6 |
| husky (tool) | 0.9.1 |
Net diff vs `develop` is only the six version bumps above. See #320 for
the full change description.
## Maintainer follow-ups (after merge)
- Add `CODEGEN_APP_CLIENT_ID` / `CODEGEN_APP_PRIVATE_KEY` (GitHub App)
to **both** Actions and Dependabot secret stores for the merge-bot.
- Let Dependabot bring `develop`'s deps up to match (or open a small
sync PR).
- Kick off the first publish via **Actions → publish-release.yml → Run
workflow** once secrets are in.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Convert to two-phase dual-publish release model - #320

Merged
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template
Jun 5, 2026
Merged

Convert to two-phase dual-publish release model#320
ptr727 merged 3 commits into
developfrom
convert-dualpublish-template

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Summary

Convert the project from publish-on-push to the ptr727/ProjectTemplatetwo-phase dual-publish release model, matching the structure already adopted by LanguageTags so future template changes apply as minimal deltas.

  • Phase 1 — PRs smoke-test only.test-pull-request.yml runs unit tests + a paths-filtered smoke build; merges no longer publish.
  • Phase 2 — weekly scheduled publish.publish-release.yml publishes both branches on a Monday 02:00 UTC cron and on manual dispatch, with idempotent no-op republish (skip release if the tag exists, --skip-duplicate on NuGet). Opt-in continuous-release via the PUBLISH_ON_MERGE repo variable.

Changes

  • Reusable workflow set: get-version-task, build-nugetlibrary-task, build-release-task, build-datebadge-task, plus publish-release, test-pull-request, and a branch-aware Dependabot merge-bot-pull-request (squash on develop / merge on main).
  • Removed BuildPublishPipeline.yml and DependabotAutoMerge.yml. NuGet.org-only (dropped the GitHub Packages push). No Docker/executable/PyPI/codegen targets.
  • Central Package Management (Directory.Build.props + Directory.Packages.props).
  • Added AGENTS.md documenting the branching/release/workflow conventions.
  • Reconciled the template's strict analyzers (AnalysisMode All + TreatWarningsAsErrors) with this brownfield library by relaxing specific rules in .editorconfig (each documented inline) and IL3058 via NoWarn; ImplicitUsings cleanup removed now-redundant usings.
  • Normalized line endings to .editorconfig and fixed the .husky/pre-commit shebang to LF + executable.

Maintainer follow-ups (not in this PR)

  • Add CODEGEN_APP_CLIENT_ID / CODEGEN_APP_PRIVATE_KEY (GitHub App) to both Actions and Dependabot secret stores for the merge-bot.
  • Bind the Check pull request workflow status required check to the develop (squash-only) and main (merge-only) rulesets.
  • Leave PUBLISH_ON_MERGE unset for the two-phase default.

🤖 Generated with Claude Code

ptr727 added 2 commits June 4, 2026 18:01
Replace publish-on-push with the ProjectTemplate/LanguageTags two-phase
model: PRs smoke-test only, and publish-release.yml publishes both branches
on a weekly schedule (Mon 02:00 UTC) or manual dispatch, with idempotent
no-op republish. Adopt the reusable workflow set (get-version,
build-nugetlibrary, build-release, build-datebadge), a branch-aware
Dependabot merge-bot, Central Package Management, and an AGENTS.md tracking
the template. NuGet.org-only (drop GitHub Packages); no Docker/exe/PyPI/codegen.
Reconcile the template's strict analyzers (AnalysisMode All +
TreatWarningsAsErrors) with the brownfield library by relaxing specific
rules in .editorconfig and IL3058 via NoWarn, all documented.
Convert the workflow YAML, dependabot.yml, and AGENTS.md (added LF) to CRLF
per .editorconfig, and make .husky/pre-commit LF + executable so its shebang
execs on Linux/WSL. Add an .editorconfig rule pinning the hook to LF.
CopilotAI review requested due to automatic review settings June 5, 2026 01:14

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

Migrates the repository’s CI/CD from the previous publish-on-push pipeline to the ProjectTemplate-aligned two-phase dual-publish model (PR smoke-test only; scheduled/manual publish of both main and develop), while introducing Central Package Management and codifying release/workflow conventions.

Changes:

  • Replaces the legacy build/publish workflows with a reusable-task workflow set, a PR-only test/smoke workflow, and a scheduled/manual publisher that can optionally publish on merge via PUBLISH_ON_MERGE.
  • Introduces Central Package Management (Directory.Build.props, Directory.Packages.props) and adjusts project files/using directives to rely on shared settings + implicit usings.
  • Adds/updates repo process documentation and configuration (AGENTS.md, .editorconfig, hook shebang/line-endings, .gitignore, README badge).

Reviewed changes

Copilot reviewed 38 out of 40 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
UtilitiesTests/UtilitiesTests.csprojRemoves per-project TFM/analyzer/version pinning to rely on shared build props + central package versions.
UtilitiesTests/UtilitiesTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringHistoryTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/StringCompressionAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/FileExAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ExtensionsTests.csUpdates null-argument extension tests and removes redundant usings as part of analyzer/implicit-using cleanup.
UtilitiesTests/DownloadTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/DownloadAsyncTests.csRemoves redundant explicit using now covered by implicit usings.
UtilitiesTests/ConsoleTests.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Utilities.csprojMoves analyzer/TFM/nullable to shared props; adds AOT warning suppression for IL3058; uses CPM.
Utilities/StringHistory.csRemoves redundant explicit using now covered by implicit usings.
Utilities/StringCompression.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Format.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileExOptions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/FileEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Extensions.csRemoves redundant explicit using now covered by implicit usings.
Utilities/Download.csRemoves redundant explicit using now covered by implicit usings.
Utilities/ConsoleEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities/CommandLineEx.csRemoves redundant explicit using now covered by implicit usings.
Utilities.slnxAdds new solution items for CPM + agent/process docs + new workflows; removes legacy workflow entries.
Sandbox/Sandbox.csprojAligns sandbox build props with shared settings + CPM; suppresses IL3058 similarly.
Sandbox/Program.csMinor cleanup to use AppContext and rely on implicit usings.
README.mdUpdates workflow-status badge to point at the new publisher workflow.
Directory.Packages.propsAdds central package version definitions for NuGet, tests, and Serilog dependencies.
Directory.Build.propsAdds shared build settings (TFM, analyzers, WarningsAsErrors, artifacts path, CPM enablement).
AGENTS.mdDocuments branching rules, release model, and workflow conventions for maintainers/agents.
.husky/pre-commitNormalizes shebang/line-endings to ensure hook runs on POSIX shells.
.gitignoreIgnores .artifacts folder produced by the shared ArtifactsPath.
.github/workflows/test-pull-request.ymlNew PR workflow: unit tests + paths-filter-gated smoke build + required-status aggregator job.
.github/workflows/publish-release.ymlNew publisher: scheduled/manual dual-branch publish, optional push-publish gated by PUBLISH_ON_MERGE.
.github/workflows/merge-bot-pull-request.ymlNew Dependabot merge-bot using App token and branch-aware merge method.
.github/workflows/get-version-task.ymlNew reusable workflow to compute NBGV version metadata with a pinned checkout ref.
.github/workflows/build-release-task.ymlNew reusable orchestrator tying versioning, NuGet build/push, and GitHub release creation together.
.github/workflows/build-nugetlibrary-task.ymlNew reusable NuGet build/push + artifact upload task, branch-config aware.
.github/workflows/build-datebadge-task.ymlNew reusable BYOB badge task gated to main.
.github/workflows/DependabotAutoMerge.ymlRemoves legacy Dependabot auto-merge workflow in favor of merge-bot model.
.github/workflows/BuildPublishPipeline.ymlRemoves legacy publish-on-push pipeline in favor of two-phase model.
.github/dependabot.ymlUpdates Dependabot config to open updates against both main and develop.
.editorconfigAdds LF override for husky hook + documents analyzer relaxations for brownfield code under strict analysis mode.

Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment threadUtilitiesTests/ExtensionsTests.cs
Comment thread.github/workflows/build-datebadge-task.yml
@ptr727
ptr727 merged commit 0e65bd2 into developJun 5, 2026
7 checks passed
@ptr727
ptr727 deleted the convert-dualpublish-template branch June 5, 2026 01:28
ptr727 added a commit that referenced this pull request Jun 5, 2026
## Summary
Land the two-phase dual-publish model on `main`, with **fully signed &
GitHub-verified history**. This is `main` merged with `develop`
(`0f1616d`), the one-time old→new structural conflicts resolved in
**develop's favour**, and the **max dependency/tool versions** taken so
`main`'s newer Dependabot bumps are not regressed.
All introduced commits are committer = `Pieter Viljoen
<ptr727@users.noreply.github.com>` and verified, satisfying
`required_signatures` (supersedes #322/#323, which carried unverifiable
web-flow-committed history).
### Dependency reconciliation (max of develop/main)
| Package / tool | Version |
| --- | --- |
| Microsoft.SourceLink.GitHub | 10.0.201 |
| Serilog | 4.3.1 |
| Microsoft.NET.Test.Sdk | 18.4.0 |
| xunit.analyzers | 1.27.0 |
| csharpier (tool) | 1.2.6 |
| husky (tool) | 0.9.1 |
Net diff vs `develop` is only the six version bumps above. See #320 for
the full change description.
## Maintainer follow-ups (after merge)
- Add `CODEGEN_APP_CLIENT_ID` / `CODEGEN_APP_PRIVATE_KEY` (GitHub App)
to **both** Actions and Dependabot secret stores for the merge-bot.
- Let Dependabot bring `develop`'s deps up to match (or open a small
sync PR).
- Kick off the first publish via **Actions → publish-release.yml → Run
workflow** once secrets are in.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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