Skip to content
Open
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
5 changes: 5 additions & 0 deletions .github/aw/actions-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
"version": "v7.0.1",
"sha": "043fb46d1a93c77aae656e7c1c64a875d1fc6a0a"
},
"github/gh-aw-actions/setup-cli@v0.79.8": {
"repo": "github/gh-aw-actions/setup-cli",
"version": "v0.79.8",
"sha": "c0338fef4749d08c21f8f975fb0e37efa17dda47"
},
"github/gh-aw-actions/setup@v0.79.8": {
"repo": "github/gh-aw-actions/setup",
"version": "v0.79.8",
Expand Down
32 changes: 29 additions & 3 deletions .github/workflows/release-notes.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 29 additions & 14 deletions .github/workflows/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ safe-outputs:
draft: true
max: 5
push-to-pull-request-branch:
title-prefix: "[release-notes] "
labels: [area-release-notes, automation]
required-title-prefix: "[release-notes] "
required-labels: [area-release-notes, automation]
max: 5
add-comment:
max: 20
Expand All @@ -47,21 +47,36 @@ on:
type: string

# ###############################################################
# Override COPILOT_GITHUB_TOKEN with a random PAT from the pool.
# Ensure this agentic jobs run from the isolated
# `copilot-pat-pool` environment where the PAT pool is available.
# This stop-gap will be removed when org billing is available.
# See: .github/workflows/shared/pat_pool.README.md for more info.
# Select a PAT from the pool and override COPILOT_GITHUB_TOKEN.
# Run agentic jobs in an isolated `copilot-pat-pool` environment.
#
# When org-level billing is available, this will be removed.
# See `shared/pat_pool.README.md` for more information.
# ###############################################################
imports:
- shared/pat_pool.md
- uses: shared/pat_pool.md
with:
environment: copilot-pat-pool

environment: copilot-pat-pool

engine:
id: copilot
env:
COPILOT_GITHUB_TOKEN: ${{ case(needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0, needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1, needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2, needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3, needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4, needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5, needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6, needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7, needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8, needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9, 'NO COPILOT PAT AVAILABLE') }}
COPILOT_GITHUB_TOKEN: |
${{ case(
needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
'NO COPILOT PAT AVAILABLE')
}}
---

# Write Release Notes
Expand Down Expand Up @@ -126,8 +141,8 @@ The shipped preview number is the **floor**. Everything above it may need work.
#### b. What's building on main (VMR)

```bash
git clone --filter=blob:none https://github.com/dotnet/dotnet /tmp/dotnet
git -C /tmp/dotnet show main:eng/Versions.props | grep -E 'PreReleaseVersionLabel|PreReleaseVersionIteration'
git clone --filter=blob:none https://github.com/dotnet/dotnet /tmp/gh-aw/agent/dotnet
git -C /tmp/gh-aw/agent/dotnet show main:eng/Versions.props | grep -E 'PreReleaseVersionLabel|PreReleaseVersionIteration'
```

This tells you the milestone `main` is building (e.g., iteration `5`).
Expand All @@ -136,10 +151,10 @@ This tells you the milestone `main` is building (e.g., iteration `5`).

```bash
# Tags — each represents a shipped or finalized milestone
git -C /tmp/dotnet tag -l 'v11.0.0-preview.*' --sort=-v:refname
git -C /tmp/gh-aw/agent/dotnet tag -l 'v11.0.0-preview.*' --sort=-v:refname

# Release branches — each represents an in-flight milestone being stabilized
git -C /tmp/dotnet branch -r -l 'origin/release/11.0.1xx-preview*'
git -C /tmp/gh-aw/agent/dotnet branch -r -l 'origin/release/11.0.1xx-preview*'
```

#### d. Build the milestone list
Expand Down Expand Up @@ -175,7 +190,7 @@ Always regenerate — the content may have changed since the previous run.

```bash
mkdir -p release-notes/11.0/preview/preview4
release-notes generate changes /tmp/dotnet \
release-notes generate changes /tmp/gh-aw/agent/dotnet \
--base v11.0.0-preview.3.26210.100 \
--head main \
--version "11.0.0-preview.4" \
Expand Down
59 changes: 49 additions & 10 deletions .github/workflows/shared/pat_pool.README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Selects a random Copilot PAT from a numbered pool of secrets. This addresses limitations that arise from having a single PAT shared across all agentic workflows, such as rate-limiting.

**This is a stop-gap workaround.** As soon as organization/enterprise billing is offered for agentic workflows, this approach will be removed from our workflows.
**This is a stop-gap workaround.** As soon as organization/enterprise billing is available to the dotnet org, this approach will be removed from our workflows.

## Repository Onboarding

Expand All @@ -19,9 +19,20 @@ gh extension install github/gh-aw --force
gh aw --version
```

### Environment

Create an environment for the agentic workflows:

- _Configuring these settings requires repo admin permission_
- `https://github.com/dotnet/{repo}/settings/environments`
- Recommended Name: **copilot-pat-pool**
- Recommended Deployment branches and tags: **Protected branches only**

This environment is used for all agentic workflows, restricting agentic workflows to the repo's protected branches and preventing the workflows from accessing secrets defined for other environments.

## PAT Management

Team members provide PATs into the pools for the repository by adding them as repository secrets with secret names matching the pattern of `<pool_name>_<0-9>`, such as `COPILOT_PAT_0`.
Team members provide PATs into the pool with secret names matching the pattern of `{pool-name}_{0-9}`, such as `COPILOT_PAT_0`.

[Use this link to prefill the PAT creation form with the required settings][create-pat]:

Expand All @@ -32,12 +43,30 @@ Team members provide PATs into the pools for the repository by adding them as re

The **Token Name** _does not_ need to match the secret name and is only visible to the owner of the PAT. It's recommended to use a token name indicating the PAT is used for dotnet org agentic workflows. The **Description** is also only used for your own reference.

Team members providing PATs for workflows should set weekly recurring reminders to regenerate and update their PATs in the repository secrets. With an 8-day expiration, renewal can be done on the same day each week.
Team members providing PATs for workflows should set weekly recurring reminders to regenerate and update their PATs in the PAT pool. With an 8-day expiration, renewal can be done on the same day each week.

## PAT Pool Secrets

For a PAT pool that is specific to an environment, PATs can be added to repositories as **Environment Secrets** for the environment created above. _This requires repo admin permission_.

- **Settings** >
- **Environments** >
- **copilot-pat-pool** (or other environment name) >
- **Add environment secret** (or edit your existing secret)
- Enter your secret name of `COPILOT_PAT_{0-9}` and paste in your PAT

This can also be accomplished using the `gh` CLI, specifying the repo and environment arguments.

PATs are added to repositories through the **Settings > Secrets and variables > Actions** UI, saved as **Repository secrets** and matching the `<pool_name>_<0-9>` naming convention. This can also be done using the GitHub CLI.
```sh
# Register the PAT secret. This will prompt for you to paste the PAT.
gh secret set "<pool_name>_<0-9>" --repo <org>/<repo> --env "copilot-pat-pool"
```

It's also helpful to record who owns each PAT within the pool. To capture which team member is associated with each PAT, a `<pool_name>_<0-9>_<username>` "sidecar secret" can be added alongside the PAT secret to make the username for the PAT pool entry visible. This sidecar secret must have a non-empty value, but it's never consumed, so any value is sufficient.

```sh
gh aw secrets set "<pool_name>_<0-9>" --value "<your-github-pat>" --repo <org>/<repo>
# Record a sidecar secret that presents who owns this PAT.
gh secret set "<pool_name>_<0-9>_<username>" --body "<username>" --repo <org>/<repo> --env "copilot-pat-pool"
```

## Workflow Output Attribution
Expand All @@ -51,16 +80,22 @@ The [`pat_pool.md`](./pat_pool.md) workflow import defines a custom job with a `
```yml
# ###############################################################
# Select a PAT from the pool and override COPILOT_GITHUB_TOKEN.
# Run agentic jobs in an isolated `copilot-pat-pool` environment.
#
# When org-level billing is available, this will be removed.
# See `shared/pat_pool.README.md` for more information.
# ###############################################################
imports:
- shared/pat_pool.md
- uses: shared/pat_pool.md
with:
environment: copilot-pat-pool

environment: copilot-pat-pool

engine:
id: copilot
env:
COPILOT_GITHUB_TOKEN: |
COPILOT_GITHUB_TOKEN: |
${{ case(
needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
Expand All @@ -72,16 +107,20 @@ engine:
needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
secrets.COPILOT_GITHUB_TOKEN)
'NO COPILOT PAT AVAILABLE')
}}
```

The expression can be collapsed onto a single line if desired. `gh-aw compile` automatically wires `pat_pool` into the activation and agent jobs' `needs:` graph because of the `needs.pat_pool.` references within the `engine.env` property.
The `COPILOT_GITHUB_TOKEN` expression can be collapsed onto a single line if desired. `gh-aw compile` automatically wires `pat_pool` into the activation and agent jobs' `needs:` graph because of the `needs.pat_pool.` references within the `engine.env` property.

```sh
gh aw compile <workflow-name> --schedule-seed <org>/<repo>
```

### Specifying the environment

The `environment` must be specified both to the `pat_pool.md` import and to the containing workflow to ensure both jobs access the PAT pool from the same environment. The `copilot-pat-pool` environment name is recommended as the isolated environment for agentic workflows that use the PAT pool.

### Customizing the pool

The import declares 10 optional inputs (`COPILOT_PAT_0` through `COPILOT_PAT_9`), each defaulting to `secrets.COPILOT_PAT_#` of the matching number. To point a workflow at a different pool of repository secrets, use the parameterized `uses`/`with` form when importing and pass the substitute secrets as the `COPILOT_PAT_#` inputs:
Expand All @@ -101,7 +140,7 @@ The secrets passed via `with:` must match the secrets referenced in the consumin
engine:
id: copilot
env:
COPILOT_GITHUB_TOKEN: ${{ case(needs.pat_pool.outputs.pat_number == '0', secrets.MY_TEAM_PAT_0, needs.pat_pool.outputs.pat_number == '1', secrets.MY_TEAM_PAT_1, ..., secrets.COPILOT_GITHUB_TOKEN) }}
COPILOT_GITHUB_TOKEN: ${{ case(needs.pat_pool.outputs.pat_number == '0', secrets.MY_TEAM_PAT_0, needs.pat_pool.outputs.pat_number == '1', secrets.MY_TEAM_PAT_1, ..., 'NO COPILOT PAT AVAILABLE') }}
```

This approach aligns with GitHub's documented guidance for [passing secrets][passing-secrets] between workflows, where the `pat_pool` job returns a PAT number and the `case` statement acts as a secret store to look the PAT secret up based on the selected number.
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/shared/pat_pool.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Agentic workflow import to integrate the Copilot PAT Pool

jobs:
pat_pool:
environment: copilot-pat-pool
environment: ${{ github.aw.import-inputs.environment }}
needs: [pre_activation]
runs-on: ubuntu-slim
outputs:
Expand Down Expand Up @@ -69,6 +69,9 @@ jobs:
echo "copilot_pat_number=${PAT_NUMBER}" >> "$GITHUB_OUTPUT"

import-schema:
environment:
type: string
required: true
COPILOT_PAT_0:
type: string
required: false
Expand Down
Loading
Loading