diff --git a/.github/agents/fsharp-release-announcement.md b/.github/agents/fsharp-release-announcement.md index c5532437faa..bd173733f2d 100644 --- a/.github/agents/fsharp-release-announcement.md +++ b/.github/agents/fsharp-release-announcement.md @@ -1,169 +1,14 @@ --- name: F# Release Announcement -description: Craft F# release announcements for .NET preview/release milestones by tracing SDK→VMR→dotnet/fsharp commit ranges, analyzing release notes, PRs, and issues, then producing a markdown article. +description: Draft and review F# release announcements for .NET preview, RC, and stable milestones using the release-notes skill's shared announcement workflow. --- -# 0. Resolve SDK branch names +# F# Release Announcement -User provides only a target release name (e.g., ".NET 11 Preview 2"). Derive everything else. +Read [F# release announcements](../skills/release-notes/references/release-announcements.md) before drafting or changing an article. -```bash -# List all release branches in dotnet/sdk -gh api repos/dotnet/sdk/branches --paginate -q '.[].name' | grep '^release/' | sort -V -``` +- From the requested release name, resolve the actual SDK branches, release baseline, parallel stable band, and immutable source pins. +- Produce one F# component article from confirmed shipped changes and relevant prior announcements. +- Use the shared workflow for selection, examples, performance evidence, attribution, review, and publication. -Branch naming pattern: `release/.0.xx-preview` or `release/.0.xx` - -From the listing, identify: -1. **Target branch**: match release name to branch (e.g., ".NET 11 Preview 2" → `release/11.0.1xx-preview2`) -2. **Previous branch**: prior preview or prior milestone (e.g., preview1 for preview2, or last stable for preview1) -3. **Parallel stable branch**: highest `.0.Xxx` branch (for exclusivity check) - -# 1. Fetch previous announcement — DO NOT REPEAT - -``` -gh api repos/dotnet/core/contents/release-notes -q '.[].name' -``` - -Navigate to latest published `fsharp.md` under `release-notes//preview/*/`. Fetch it. Every item in it is excluded from output. - -# 2. Resolve F# commit range - -**CRITICAL**: Use SDK, not VMR branch. VMR branch may have newer F# than what SDK locked in. - -### Get F# end commit (target release) - -``` -# 1. SDK → VMR hash (find the Dependency for Microsoft.FSharp.Compiler, extract its Sha) -gh api repos/dotnet/sdk/contents/eng/Version.Details.xml?ref=release/11.0.1xx-preview2 | jq -r '.content' | base64 -d | grep -A2 'Microsoft.FSharp.Compiler' | grep Sha | sed 's/.*>\([a-f0-9]*\)<.*/\1/' -# Result: VMR_HASH - -# 2. VMR → F# hash -gh api repos/dotnet/dotnet/contents/src/source-manifest.json?ref=VMR_HASH | jq -r '.content' | base64 -d | jq -r '.repositories[] | select(.path=="fsharp") | .commitSha' -# Result: FSHARP_END -``` - -### Get F# start commit (previous release) - -Repeat above with previous SDK branch (e.g., `release/11.0.1xx-preview1`). -Result: `FSHARP_START` - -### Cross-check with parallel SDK branch - -Repeat for `release/10.0.3xx` (or current stable band). Compare F# hash. Determine if features are shared or exclusive. - -# 3. Diff release notes - -```bash -git diff FSHARP_START..FSHARP_END -- docs/release-notes/ | grep '^+' | grep -v '^+++' -``` - -Source files: -- `docs/release-notes/.FSharp.Compiler.Service/*.md` -- `docs/release-notes/.FSharp.Core/*.md` -- `docs/release-notes/.Language/*.md` -- `docs/release-notes/.VisualStudio/*.md` - -### EXCLUDE - -- Already in previous announcement -- CI, infra, test-only, repo maintenance, dependency updates, localization -- FCS-internal API (unless enables user scenario) -- xUnit migration, build scripts, baseline updates - -# 4. Investigate each entry via sub-agents - -For each user-facing release note entry, spawn a sub-agent (explore or general-purpose) to investigate it independently. Each sub-agent writes its findings to a temp file. - -``` -For each entry with PR #NUMBER: - - Launch sub-agent with prompt: - """ - Investigate dotnet/fsharp PR #NUMBER. - 1. Get PR author, title, description, linked issues - 2. Get files changed — classify as: feature / bugfix / test-only / infra - 3. If feature or significant bugfix: - - Find test files: git diff-tree --no-commit-id -r --name-only | grep -i test - - Extract the most illustrative code sample from the tests (real F# code, not test harness) - - Note benchmark data if PR description has any - 4. If author is NOT T-Gro, Copilot, or abonie → mark as community contributor - 5. Write findings to /tmp/release-notes/pr-NUMBER.md in this format: - - ## PR #NUMBER: - - Author: <login> (community: yes/no) - - Type: feature | bugfix | api | perf | infra - - One-line summary: <what changed for users> - - Issue(s): #X, #Y - - Code sample (if feature/api): - ```fsharp - <code from tests> - ``` - - Benchmark (if perf): - <table or numbers from PR> - """ -``` - -Run sub-agents in parallel (up to 5). Wait for all to complete. Read all `/tmp/release-notes/pr-*.md` files to assemble the full picture. - -Skip entries where sub-agent classified as `infra` or `test-only`. - -# 5. Write the article - -## Attribution - -- Community contributors: `Thanks to [**user**](https://github.com/user)` with link -- NEVER mention: T-Gro, Copilot, abonie (internal) -- Credit community even if their PR was superseded (e.g., "Inspired by [**user**]'s work in #XXXX") - -## Structure - -```markdown -# F# in .NET XX Preview Y - Release Notes - -Here's a summary of what's new in F# in this Preview Y release: - -- [Highlight 1](#anchor) -- [Highlight 2](#anchor) -- [Category 1](#anchor) -- [Category 2](#anchor) -- [Bug fixes](#bug-fixes-and-other-improvements) - -## Highlight 1 ← 1-3 sections, CODE SAMPLES from tests, minimal prose -## Highlight 2 -## Category: Query fixes ← bullet list with issue links, no code -## Category: IDE fixes ← bullet list -## Bug fixes ← flat bullet list, prefixed by area (Nullness:, Scripts:, etc.) - -F# updates: -- [F# release notes](https://fsharp.github.io/fsharp-compiler-docs/release-notes/About.html) -- [dotnet/fsharp repository](https://github.com/dotnet/fsharp) -``` - -## Highlight selection (pick 1-3) - -Rank by: language feature > new API > perf win with numbers > significant bug fix area -Each MUST have code sample extracted from PR tests. No invented examples. - -## Style - -- One-sentence intro max, then code block or table -- No fluff, no "we are excited", no "this release brings" -- Bold key terms in bullet lists -- Link every issue and PR number - -# SDK branch naming - -| Release | Branch | -|---|---| -| .NET 11 Preview N | `release/11.0.1xx-previewN` | -| .NET 10.0.X00 | `release/10.0.Xxx` | - -# Key files - -| Repo | Path | Contains | -|---|---|---| -| dotnet/sdk | `eng/Version.Details.xml` | VMR commit SHA | -| dotnet/dotnet | `src/source-manifest.json` | F# commit SHA | -| dotnet/fsharp | `docs/release-notes/` | Per-version changelogs | -| dotnet/core | `release-notes/` | Published announcements | +For a per-PR changelog entry, use the [release-notes skill](../skills/release-notes/SKILL.md#version) instead. diff --git a/.github/skills/release-notes/SKILL.md b/.github/skills/release-notes/SKILL.md index 1ae90a439c9..d0aa2b21d96 100644 --- a/.github/skills/release-notes/SKILL.md +++ b/.github/skills/release-notes/SKILL.md @@ -1,10 +1,17 @@ --- name: release-notes -description: Write release notes for completed changes. Use when PR modifies tracked paths and needs release notes entry. +description: Write per-PR changelog entries for completed F# changes, or draft and review F# release announcements and articles for .NET preview, RC, and stable milestones. --- # Release Notes +## Choose the task + +- **Per-PR changelog entry:** Use the rules below when a PR changes tracked paths. +- **Milestone announcement:** Read [F# release announcements](references/release-announcements.md) before drafting or reviewing a .NET/F# release article. + +The announcement workflow does not replace the per-PR helper or CI check. + ## Version From GitHub repo variable `VNEXT` (e.g., `10.0.300`) - Language: `preview.md` diff --git a/.github/skills/release-notes/references/release-announcements.md b/.github/skills/release-notes/references/release-announcements.md new file mode 100644 index 00000000000..5143e11b6bc --- /dev/null +++ b/.github/skills/release-notes/references/release-announcements.md @@ -0,0 +1,123 @@ +# F# release announcements + +Use this workflow to draft or review one F# component article for a .NET milestone. +For per-PR changelog entries, use the [release-notes skill](../SKILL.md#version). + +## 1. Establish scope + +- Confirm the milestone, publication repository, article path, PR source branch, target branch, and draft state. +- Limit publication changes to the article, its component index link, and explicitly approved companion reports or media. +- Keep skill updates in a separate documentation PR, never in a release article PR. +- Store research, validation projects, and logs in session storage. Commit maintained fixtures only within explicit or agreed task scope. +- Do not delete existing author files without approval. +- Work directly by default. Use bounded, grouped research only when needed or requested, not one sub-agent per PR. +- Do not hardcode models or an automatic review panel. Honor an explicitly requested review setup. +- Do not generate whole-.NET metadata, schemas, or branch sets unless the task requires those publication contracts. + +## 2. Prove release inclusion + +Discover actual SDK branches rather than constructing a branch name from the milestone: + +```bash +gh api repos/dotnet/sdk/branches --paginate --jq '.[].name' +``` + +Resolve the target release, preceding milestone, and parallel stable SDK band. +Confirm the release identity from official release metadata. +Resolve release tags to commit SHAs for each comparison: + +| Source | Read at the resolved commit | Record | +| --- | --- | --- | +| `dotnet/sdk` | `eng/Version.Details.xml`, dependency `Microsoft.FSharp.Compiler` | Dependency repository URI and SHA | +| `dotnet/dotnet` | `src/source-manifest.json` at that pinned VMR SHA | `commitSha` for repository path `fsharp` | +| `dotnet/fsharp` | Source and `docs/release-notes/` at the F# SHA | Baseline and target source pins | + +- Follow the dependency URI and SHA. If the source repository differs, verify the pin chain rather than assuming VMR. +- Use the official SDK's pinned payload, not a newer SDK or VMR branch head. Branch shorthand is not shipping proof. +- Compare target and baseline F# pins. Check the parallel stable band for shared or earlier availability. +- Read the whole commit range, merged PRs, and release-note files at both pins. +- Compare actual baseline changelog content. Random insertion and entry movement are not new features. +- Do not discover changes from added diff lines, manifest scores, or PR titles alone. +- Check implementation, tests, reverts, and required dependencies at the target pin. Exclude reverted and unshipped work. +- Confirm real user scenarios. Exclude maintenance, CI, localization, and test-only work without user impact. +- Include compiler-service APIs when they enable a user scenario. Scope IDE features to the product that actually ships them. +- Distinguish source-built reports from official SDK results. Name compiler, library, runtime, and packaging differences. + +## 3. Select and explain the news + +- Read multiple relevant published `fsharp.md` articles in `dotnet/core/release-notes/`. +- Compare voice, structure, size, and section proportions. Audit important omissions beyond the initial draft. +- Remove unchanged features already announced, including preview status reminders. Describe meaningful state changes as deltas. +- Include earlier-shipped, unannounced work only when requested. State its actual availability, not a false current-milestone introduction. +- Follow explicit user priorities. Otherwise, rank by reader impact and group related changes. +- Give major capabilities and broad, default-enabled application or library benefits suitable visibility. +- Treat library-author foundations as important when their enabled scenarios justify coverage. +- Use established feature names in headings and the opening table of contents. Keep both in the same order. +- Explain concrete benefits positively in the body. Match predecessor proportions, not a fixed highlight quota or one-sentence cap. +- Read implementation tests for meaningful capability scenarios. Adapt illustrative source-tested examples, not only the smallest syntax example. +- Do not treat negative or skipped tests, or unmet source conditions, as proof of successful behavior. +- A validated prototype or test-only integration can demonstrate shipped enabling capability. Label the integration as prototype or test-only. +- Do not present that integration as shipped stock-library support or guarantee its future release. +- State a library-author-first audience near the feature introduction. +- Distinguish shipped compiler mechanics and enabling APIs from stock-library support and prototype integrations. +- Explain the adoption path without dismissing foundations or promising integrations that do not ship. +- Define required `LangVersion` or feature opt-in once near the opening. +- Mark affected sections **Preview** and refer to that setup. Do not repeat XML or CLI setup in each section. +- Check exact gates in pinned source. For SDK availability claims, also check the exact milestone SDK. +- Keep default-enabled performance and FSharp.Core changes distinct from preview language features. +- Separate migration guidance for the previous stable release from changes affecting only earlier previews. +- Group related bug fixes by user effect. Link issues and PRs rather than listing implementation changes. + +## 4. Present performance evidence + +- Separate FSharp.Core savings in running applications from compiler, FCS, and IDE compilation or memory improvements. +- Group related PRs into coherent categories. Explain who benefits and how they adopt the change. +- Name the measured metric: allocated bytes, closure counts, retained heap, peak RSS, CPU time, or wall time. +- Identify baselines, workloads, hardware, and measured cohorts. Preserve regressions, uncertainty, and limits. +- Use representative comparisons. Do not add unrelated percentages or turn workload results into universal build-speed claims. +- Keep accurate author-provided rounded summaries. Do not invent precision or measurements. +- Distinguish checked author-provided presentation from independent reruns and public raw reproducibility. +- Label full-cycle companion reports when their baseline is broader than the article's milestone comparison. +- When adding a deeper report, keep the article's useful summary. Add a motivated relative link beside that summary. +- Add a prominent opening link when requested or important for report discovery. + +## 5. Preserve attribution + +- Check actual PR authors and contribution history. Do not infer community eligibility solely from labels. +- Credit community contributors with `Thanks to [**user**](https://github.com/user)`. +- Preserve credit for superseded contributions when they inspired the shipped work. +- Do not credit T-Gro, Copilot, or abonie as community contributors. Exclude bot accounts. + +## 6. Validate the publication + +- Validate changed examples and claims against the exact milestone SDK in scratch projects outside the publication repository. +- Check the claimed behavior, not only compilation. Keep commands, results, and logs in session storage. +- For prose or title edits, use scoped Markdown and link checks. Do not start new builds or unrelated benchmarks. +- Reuse valid completed evidence. Bound research to the task and required publication checks, especially during urgent edits. +- Report missing methodology or raw-result references while the author can still retrieve them. Do not invent URLs. +- When raw references are missing, require report-specific approval before publication. That approval is not a waiver for other reports. +- Preserve true author-provided or source-built scope. Missing references cannot support claims of independent verification or public reproducibility. +- If necessary evidence remains unavailable, report the gap. Do not mark an unverified claim as confirmed. +- Inspect supplied packages, article references, assets, and provenance before import. Do not execute package code. +- Import only the approved article and required media. Exclude archives, datasets, generators, extra READMEs, and scripts unless requested. +- Check SVGs for scripts and external content. Verify alt text and repository media paths. +- Preserve navigation-only milestone indexes by default. Change that convention only on explicit user request. +- Preserve other component links. Use the actual index, such as `README.md`, rather than inventing `index.md`. +- Check relative article links, anchors, the table of contents, and media references. +- After renames or deletions, repair affected references. +- Use Markdown links for every issue and PR reference. +- Verify remote PRs, source objects, and redirects. Use the authenticated GitHub API when needed to verify source objects. +- Report ignored URLs, rate limits such as HTTP 429, and unavailable checks separately. None confirms link availability. +- Review factual scope, omissions, examples, preview setup, metrics, attribution, and the complete publication diff. +- When reviewers are requested, check voice, style, and importance separately. Record predecessor files each reviewer actually read. +- A prompt that names files is not proof of reading them. Report multiple models only if those models actually participated. + +## 7. Publish only through the intended PR + +- Check the current PR head and source branch before edits or pushes. +- Use ordinary commits and non-force pushes to that source branch only. +- Preserve the PR base and draft state unless authorized to change them. +- Never push to `main` or the target branch. Do not enable agent merge or merge the PR. +- Verify the live remote branch and PR head SHA after a push. +- Report the exact branch and SHA, plus whole-PR file count and additions/deletions against the base. +- Distinguish local, committed, pushed, and merged work. Do not report only the latest patch as the complete PR.