Skip to content

Commit 63bc52b

Browse files
authored
Merge branch 'main' into claude/contributing-make-a-contribution-link
2 parents c2c3744 + 935221f commit 63bc52b

26 files changed

Lines changed: 596 additions & 239 deletions

File tree

‎.github/workflows/check-for-spammy-prs.yml‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: Check for Spammy PRs
22

33
# Flags low-value public PRs and closes PRs that target branches other than main.
4+
# Maintainers add the skip-spammy-check label to exempt a PR.
45

56
on:
67
pull_request_target:
@@ -16,7 +17,8 @@ jobs:
1617
name: Label spammy PRs and reject non-main targets
1718
if: >
1819
github.repository == 'github/docs' && github.event_name == 'pull_request_target' &&
19-
github.event.pull_request.user.login != 'docs-bot'
20+
github.event.pull_request.user.login != 'docs-bot' &&
21+
!contains(github.event.pull_request.labels.*.name, 'skip-spammy-check')
2022
runs-on: ubuntu-latest
2123
steps:
2224
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
@@ -102,6 +104,18 @@ jobs:
102104
onlyRenames ||
103105
onlyIndexMd
104106
) {
107+
// The payload can predate a label added right after the PR opened, so read the labels again.
108+
const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({
109+
owner,
110+
repo,
111+
issue_number: pull_number,
112+
per_page: 100,
113+
})
114+
if (currentLabels.some(label => label.name.toLowerCase() === 'skip-spammy-check')) {
115+
core.info('Skipping because the pull request has the skip-spammy-check label.')
116+
return
117+
}
118+
105119
await github.rest.issues.addLabels({
106120
owner,
107121
repo,

‎.github/workflows/close-on-invalid-label.yaml‎

Lines changed: 104 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
name: Close issue/PR on adding invalid label
22

33
# Closes public issues and PRs when the invalid label is added.
4+
# Re-closes invalid PRs that someone without write access reopens.
5+
# Reopens PRs closed as invalid when maintainers add the skip-spammy-check label.
46

57
on:
68
issues:
79
types: [labeled]
8-
# pull_request_target lets the workflow close forked PRs after the invalid label is added.
10+
# pull_request_target lets the workflow close or reopen forked PRs when they're labeled or reopened.
911
pull_request_target:
10-
types: [labeled]
12+
types: [labeled, reopened]
1113

1214
permissions:
1315
contents: read
14-
issues: write
15-
pull-requests: write
1616

1717
jobs:
1818
close-on-adding-invalid-label:
1919
if: github.repository == 'github/docs' && github.event.label.name == 'invalid'
2020
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
issues: write
24+
pull-requests: write
2125

2226
steps:
2327
- name: Close issue
@@ -42,3 +46,99 @@ jobs:
4246
if: ${{ failure() && github.event_name != 'pull_request_target' }}
4347
with:
4448
slack_token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
49+
50+
# Authors can reopen PRs they closed themselves, even after the invalid label is added.
51+
reclose-reopened-invalid-pr:
52+
if: >
53+
github.repository == 'github/docs' && github.event_name == 'pull_request_target' &&
54+
github.event.action == 'reopened' &&
55+
contains(github.event.pull_request.labels.*.name, 'invalid')
56+
runs-on: ubuntu-latest
57+
permissions:
58+
pull-requests: write
59+
steps:
60+
- name: Re-close PR unless reopened by someone with write access
61+
env:
62+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63+
PR_URL: ${{ github.event.pull_request.html_url }}
64+
SENDER: ${{ github.event.sender.login }}
65+
run: |
66+
if ! permission=$(gh api "repos/$GITHUB_REPOSITORY/collaborators/$SENDER/permission" --jq '.permission'); then
67+
echo "::warning::Couldn't look up permission for $SENDER, so treating them as read-only."
68+
permission=none
69+
fi
70+
if [[ "$permission" == "admin" || "$permission" == "write" ]]; then
71+
echo "$SENDER has $permission access, so leaving the PR open."
72+
exit 0
73+
fi
74+
gh pr close "$PR_URL" --comment 'This pull request is labeled `invalid`, so only maintainers can reopen it. If you think this is incorrect, please mention this in a corresponding issue.'
75+
76+
# Maintainers add skip-spammy-check to recover a PR that automated checks closed as invalid.
77+
reopen-on-adding-skip-label:
78+
if: github.repository == 'github/docs' && github.event_name == 'pull_request_target' && github.event.label.name == 'skip-spammy-check'
79+
runs-on: ubuntu-latest
80+
permissions:
81+
contents: read
82+
steps:
83+
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
84+
with:
85+
# A PAT makes the reopen trigger other workflows, such as triage, like a manual reopen.
86+
github-token: ${{ secrets.DOCS_BOT_PAT_BASE }}
87+
script: |
88+
const { owner, repo } = context.repo
89+
const pull_number = context.payload.pull_request.number
90+
91+
// The event payload can be stale by the time this job runs, so read the current state.
92+
const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number })
93+
const labels = pr.labels.map(label => label.name.toLowerCase())
94+
95+
if (pr.merged || pr.state !== 'closed') {
96+
core.info('The pull request is not closed, so there is nothing to reopen.')
97+
return
98+
}
99+
100+
if (!labels.includes('skip-spammy-check')) {
101+
core.info('The pull request no longer has the skip-spammy-check label.')
102+
return
103+
}
104+
105+
// Automated checks add the invalid label before closing, so PRs without it were closed for another reason.
106+
if (!labels.includes('invalid')) {
107+
core.info('The pull request was not closed as invalid, so it stays closed.')
108+
return
109+
}
110+
111+
try {
112+
await github.rest.pulls.update({ owner, repo, pull_number, state: 'open' })
113+
} catch (error) {
114+
if (error.status !== 422) throw error
115+
116+
// GitHub refuses to reopen a PR after its head or base branch was deleted or force-pushed.
117+
core.warning(`Could not reopen the pull request: ${error.message}`)
118+
await github.rest.issues.createComment({
119+
owner,
120+
repo,
121+
issue_number: pull_number,
122+
body: 'I could not reopen this pull request automatically, most likely because its head or base branch was deleted or force-pushed after it was closed. Restore the branch, then remove and re-add the `skip-spammy-check` label to retry automatic reopening and removal of the `invalid` label.',
123+
})
124+
return
125+
}
126+
127+
try {
128+
await github.rest.issues.removeLabel({
129+
owner,
130+
repo,
131+
issue_number: pull_number,
132+
name: 'invalid',
133+
})
134+
} catch (error) {
135+
// A maintainer or an earlier run may have removed the label already.
136+
if (error.status !== 404) throw error
137+
}
138+
139+
await github.rest.issues.createComment({
140+
owner,
141+
repo,
142+
issue_number: pull_number,
143+
body: 'The `skip-spammy-check` label was added, so I removed the `invalid` label and reopened this pull request. The spammy pull request check skips it while the label is applied.',
144+
})

‎.github/workflows/close-prs-not-targeting-main.yml‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Reject PRs targeting non-default branch (scheduled)
22

3-
# Backup check for check-for-spammy-prs.yml: closes PRs that don't target main
3+
# Backup check for check-for-spammy-prs.yml: closes PRs that don't target main, unless they have the skip-spammy-check label
44

55
on:
66
schedule:
@@ -39,6 +39,9 @@ jobs:
3939
if (pr.user.login === 'docs-bot') continue
4040
4141
const labels = pr.labels.map(l => l.name)
42+
// Maintainers add this label to allow a PR that targets another branch.
43+
if (labels.some(label => label.toLowerCase() === 'skip-spammy-check')) continue
44+
4245
if (!labels.includes('invalid')) {
4346
await github.rest.issues.addLabels({
4447
owner,

‎.github/workflows/codeql.yml‎

Lines changed: 0 additions & 49 deletions
This file was deleted.

‎.github/workflows/repo-sync.yml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ jobs:
3030
persist-credentials: false
3131
- name: Sync repo to branch
3232
env:
33-
SOURCE_REPO: https://${{ secrets.DOCS_BOT_PAT_REPO_SYNC }}@github.com/github/${{ github.repository == 'github/docs-internal' && 'docs' || 'docs-internal' }}.git
33+
# https://github.com/actions/runner-images/issues/15014
34+
SOURCE_REPO: https://x-access-token:${{ secrets.DOCS_BOT_PAT_REPO_SYNC }}@github.com/github/${{ github.repository == 'github/docs-internal' && 'docs' || 'docs-internal' }}.git
3435
SOURCE_BRANCH: main
3536
DESTINATION_BRANCH: repo-sync
3637
GH_TOKEN: ${{ secrets.DOCS_BOT_PAT_REPO_SYNC }}

‎content/admin/data-residency/github-copilot-with-data-residency.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ The models available for {% data variables.product.prodname_copilot_short %} var
7171
* {% data variables.copilot.claude_opus_55 %}
7272
* {% data variables.copilot.claude_sonnet_5 %}
7373
* {% data variables.copilot.claude_sonnet_55 %}
74+
* {% data variables.copilot.gemini_4_argon %}
7475

7576
## Pricing changes
7677

‎content/billing/concepts/product-billing/cloud-and-local-sandboxes.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ You pay for cloud sandboxes using the payment method set up for your {% data var
6161

6262
Cloud sandbox usage is billed to the account that owns the sandbox.
6363

64-
You are prompted to select an owner for the session only if you are not currently in a Git repository. In this case, when you create a cloud sandbox session with `copilot ‑‑cloud`, you are prompted to select an owner—your own personal account is listed first, ahead of any organizations you belong to. You must choose either your personal account or one of the listed organizations, and all usage for that session is billed to the account you select.
64+
You are prompted to select an owner for the session only if you are not currently in a Git repository. In this case, when you create a cloud sandbox session with `copilot --cloud`, you are prompted to select an owner—your own personal account is listed first, ahead of any organizations you belong to. You must choose either your personal account or one of the listed organizations, and all usage for that session is billed to the account you select.
6565

6666
If you are in a repository, the owner of the repository is billed and no owner selection is required.
6767

‎content/code-security/how-tos/secure-your-secrets/customize-leak-detection/exclude-folders-and-files.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ category:
1717

1818
You may have a reason to commit a secret to a repository, such as when you want to provide a fake secret in documentation, or in an example application. In these scenarios, you can quickly dismiss the alert and document the reasons. However, there may be cases where you want to ignore a directory entirely to avoid creating false positive alerts at scale. For example, you might have a monolithic application with several integrations containing a file of dummy keys that could set off numerous false alerts to triage.
1919

20-
You can configure a `secret_scanning.yml` file to automatically close alerts found in specific directories from {% data variables.product.prodname_secret_scanning %}, and exclude these directories included in push protection. These alerts are closed as "ignored by configuration".
20+
You can configure a `secret_scanning.yml` file to automatically close alerts found in specific directories from {% data variables.product.prodname_secret_scanning %}, and exclude these directories included in push protection. These alerts are closed as "ignored by configuration". They do not trigger `secret_scanning_alert` or `secret_scanning_alert_location` webhook events.
2121

2222
## Excluding directories from {% data variables.secret-scanning.user_alerts %}
2323

0 commit comments

Comments
 (0)