Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 7 additions & 162 deletions .github/agents/fsharp-release-announcement.md
Original file line number Diff line number Diff line change
@@ -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/<major>.0.<band>xx-preview<N>` or `release/<major>.0.<band>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 `<major-1>.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/<major>/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 <MERGE_SHA> --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: <title>
- 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.
9 changes: 8 additions & 1 deletion .github/skills/release-notes/SKILL.md
Original file line number Diff line number Diff line change
@@ -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`
Expand Down
123 changes: 123 additions & 0 deletions .github/skills/release-notes/references/release-announcements.md
Original file line number Diff line number Diff line change
@@ -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.
Loading