Skip to content

Repo sync #38876

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 12, 2025
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
5 changes: 4 additions & 1 deletion data/reusables/reminders/scheduled-reminders-limitations.md
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
{% data variables.product.github %} will only trigger reminders for up to five repositories per owner and 20 pull requests per repository. Reminders are not sent when changes are merged from upstream into a fork.
Reminders will only be triggered for up to five repositories per scheduled reminder. Users can either select up to five specific repositories or allow the system to automatically choose the five repositories with the oldest average pull request age. For each repository, up to 20 of the oldest pull requests will be shown.

> [!NOTE]
> Reminders are not sent when changes are merged from upstream into a fork.
80 changes: 78 additions & 2 deletions src/workflows/ready-for-docs-review.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,58 @@ import {
getSize,
} from './projects.js'

/**
* Determines if a PR is authored by Copilot and extracts the human assignee
* @param data GraphQL response data containing PR information
* @returns Object with isCopilotAuthor boolean and copilotAssignee string
*/
function getCopilotAuthorInfo(data: Record<string, any>): {
isCopilotAuthor: boolean
copilotAssignee: string
} {
// Check if this is a Copilot-authored PR
const isCopilotAuthor =
data.item.__typename === 'PullRequest' &&
data.item.author &&
data.item.author.login === 'copilot-swe-agent'

// For Copilot PRs, find the appropriate assignee (excluding Copilot itself)
let copilotAssignee = ''
if (isCopilotAuthor && data.item.assignees && data.item.assignees.nodes) {
const assignees = data.item.assignees.nodes
.map((assignee: Record<string, any>) => assignee.login)
.filter((login: string) => login !== 'copilot-swe-agent')

// Use the first non-Copilot assignee
copilotAssignee = assignees.length > 0 ? assignees[0] : ''
}

return { isCopilotAuthor, copilotAssignee }
}

/**
* Determines the appropriate author field value based on contributor type
* @param isCopilotAuthor Whether the PR is authored by Copilot
* @param copilotAssignee The human assignee for Copilot PRs (empty string if none)
* @param firstTimeContributor Whether this is a first-time contributor
* @returns The formatted author field value
*/
function getAuthorFieldValue(
isCopilotAuthor: boolean,
copilotAssignee: string,
firstTimeContributor: boolean | undefined,
): string {
if (isCopilotAuthor) {
return copilotAssignee ? `Copilot + ${copilotAssignee}` : 'Copilot'
}

if (firstTimeContributor) {
return ':star: first time contributor'
}

return process.env.AUTHOR_LOGIN || ''
}

async function run() {
// Get info about the docs-content review board project
const data: Record<string, any> = await graphql(
Expand Down Expand Up @@ -48,6 +100,14 @@ async function run() {
path
}
}
author {
login
}
assignees(first: 10) {
nodes {
login
}
}
}
}
}
Expand Down Expand Up @@ -141,17 +201,31 @@ async function run() {
}
}
const turnaround = process.env.REPO === 'github/docs' ? 3 : 2

// Check if this is a Copilot-authored PR and get the human assignee
const { isCopilotAuthor, copilotAssignee } = getCopilotAuthorInfo(data)

// Determine the author field value
const authorFieldValue = getAuthorFieldValue(
isCopilotAuthor,
copilotAssignee,
firstTimeContributor,
)

// Generate a mutation to populate fields for the new project item
const updateProjectV2ItemMutation = generateUpdateProjectV2ItemFieldMutation({
item: newItemID,
author: firstTimeContributor ? ':star: first time contributor' : process.env.AUTHOR_LOGIN || '',
author: authorFieldValue,
turnaround,
feature,
})

// Determine which variable to use for the contributor type
let contributorType
if (await isDocsTeamMember(process.env.AUTHOR_LOGIN || '')) {
if (isCopilotAuthor) {
// Treat Copilot PRs as Docs team
contributorType = docsMemberTypeID
} else if (await isDocsTeamMember(process.env.AUTHOR_LOGIN || '')) {
contributorType = docsMemberTypeID
} else if (await isGitHubOrgMember(process.env.AUTHOR_LOGIN || '')) {
contributorType = hubberTypeID
Expand Down Expand Up @@ -185,6 +259,8 @@ async function run() {
return newItemID
}

export { run }

run().catch((error) => {
console.log(`#ERROR# ${error}`)
process.exit(1)
Expand Down
Loading