-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into webkit-video
- Loading branch information
Showing
34 changed files
with
1,015 additions
and
174 deletions.
There are no files selected for viewing
4 changes: 2 additions & 2 deletions
4
.github/workflows/add_to_triage_project.yml → .github/workflows/triage_add_to_project.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
name: 'Triage: route to team project board' | ||
on: | ||
issues: | ||
types: | ||
- labeled | ||
jobs: | ||
route-to-e2e: | ||
if: github.event.label.name == 'routed-to-e2e' | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Get project data | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_TOKEN }} | ||
ORGANIZATION: 'cypress-io' | ||
PROJECT_NUMBER: 10 | ||
run: | | ||
gh api graphql -f query=' | ||
query($org: String!, $number: Int!) { | ||
organization(login: $org){ | ||
projectV2(number: $number) { | ||
id | ||
} | ||
} | ||
}' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json | ||
echo 'PROJECT_ID='$(jq -r '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV | ||
- name: add issue to e2e project | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_TOKEN }} | ||
ISSUE_ID: ${{ github.event.issue.node_id }} | ||
run: | | ||
gh api graphql -f query=' | ||
mutation($project:ID!, $issue:ID!) { | ||
addProjectV2ItemById(input: {projectId: $project, contentId: $issue}) { | ||
item { | ||
id | ||
} | ||
} | ||
}' -f project=$PROJECT_ID -f issue=$ISSUE_ID |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
name: 'Triage: closed issue comment' | ||
on: | ||
issue_comment: | ||
types: | ||
- created | ||
jobs: | ||
move-to-new-issue-status: | ||
if: | | ||
!github.event.issue.pull_request && | ||
github.event.issue.state == 'closed' && | ||
github.event.comment.created_at != github.event.issue.closed_at && | ||
github.event.sender.login != 'cypress-bot' | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Get project data | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_TOKEN }} | ||
ORGANIZATION: 'cypress-io' | ||
REPOSITORY: 'cypress' | ||
PROJECT_NUMBER: 9 | ||
ISSUE_NUMBER: ${{ github.event.issue.number }} | ||
run: | | ||
gh api graphql -f query=' | ||
query($org: String!, $repo: String!, $project: Int!, $issue: Int!) { | ||
organization(login: $org) { | ||
repository(name: $repo) { | ||
issue(number: $issue) { | ||
projectItems(first: 10, includeArchived: false) { | ||
nodes { | ||
id | ||
fieldValueByName(name: "Status") { | ||
... on ProjectV2ItemFieldSingleSelectValue { | ||
name | ||
field { | ||
... on ProjectV2SingleSelectField { | ||
project { | ||
... on ProjectV2 { | ||
id | ||
number | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
projectV2(number: $project) { | ||
field(name: "Status") { | ||
... on ProjectV2SingleSelectField { | ||
id | ||
options { | ||
id | ||
name | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}' -f org=$ORGANIZATION -f repo=$REPOSITORY -F issue=$ISSUE_NUMBER -F project=$PROJECT_NUMBER > project_data.json | ||
echo 'PROJECT_ID='$(jq -r '.data.organization.repository.issue.projectItems.nodes[].fieldValueByName.field.project | select(.number == ${{ env.PROJECT_NUMBER }}) | .id' project_data.json) >> $GITHUB_ENV | ||
echo 'PROJECT_ITEM_ID='$(jq -r '.data.organization.repository.issue.projectItems.nodes[] | select(.fieldValueByName.field.project.number == ${{ env.PROJECT_NUMBER }}) | .id' project_data.json) >> $GITHUB_ENV | ||
echo 'STATUS_FIELD_ID='$(jq -r '.data.organization.projectV2.field | .id' project_data.json) >> $GITHUB_ENV | ||
echo 'STATUS='$(jq -r '.data.organization.repository.issue.projectItems.nodes[].fieldValueByName | select(.field.project.number == ${{ env.PROJECT_NUMBER }}) | .name' project_data.json) >> $GITHUB_ENV | ||
echo 'NEW_ISSUE_OPTION_ID='$(jq -r '.data.organization.projectV2.field.options[] | select(.name== "New Issue") | .id' project_data.json) >> $GITHUB_ENV | ||
- name: Move issue to New Issue status | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_TOKEN }} | ||
if: env.STATUS == 'Closed' | ||
run: | | ||
gh api graphql -f query=' | ||
mutation ( | ||
$project: ID! | ||
$item: ID! | ||
$status_field: ID! | ||
$status_value: String! | ||
) { | ||
updateProjectV2ItemFieldValue(input: { | ||
projectId: $project | ||
itemId: $item | ||
fieldId: $status_field | ||
value: { | ||
singleSelectOptionId: $status_value | ||
} | ||
}) { | ||
projectV2Item { | ||
id | ||
} | ||
} | ||
}' -f project=$PROJECT_ID -f item=$PROJECT_ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value=$NEW_ISSUE_OPTION_ID |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
name: 'Triage: issue metrics' | ||
|
||
on: | ||
workflow_dispatch: | ||
inputs: | ||
startDate: | ||
description: 'Start date (YYYY-MM-DD)' | ||
type: date | ||
endDate: | ||
description: 'End date (YYYY-MM-DD)' | ||
type: date | ||
jobs: | ||
seven-day-close: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/github-script@v6 | ||
env: | ||
ORGANIZATION: 'cypress-io' | ||
REPOSITORY: 'cypress' | ||
PROJECT_NUMBER: 9 | ||
with: | ||
github-token: ${{ secrets.ADD_TO_PROJECT_TOKEN }} | ||
script: | | ||
const ROUTED_TO_LABELS = ['routed-to-e2e', 'routed-to-ct'] | ||
const MS_PER_DAY = 1000 * 60 * 60 * 24 | ||
const { REPOSITORY, ORGANIZATION, PROJECT_NUMBER } = process.env | ||
const issues = [] | ||
const determineDateRange = () => { | ||
const inputStartDate = '${{ inputs.startDate }}' | ||
const inputEndDate = '${{ inputs.endDate }}' | ||
if (inputStartDate && inputEndDate) { | ||
return { startDate: inputStartDate, endDate: inputEndDate } | ||
} | ||
if (inputStartDate || inputEndDate) { | ||
core.setFailed('Both startDate and endDate are required if one is provided.') | ||
} | ||
const startDate = new Date() | ||
startDate.setDate(startDate.getDate() - 6) | ||
return { startDate: startDate.toISOString().split('T')[0], endDate: (new Date()).toISOString().split('T')[0] } | ||
} | ||
const dateRange = determineDateRange() | ||
const query = `is:issue+repo:${ORGANIZATION}/${REPOSITORY}+project:${ORGANIZATION}/${PROJECT_NUMBER}+created:${dateRange.startDate}..${dateRange.endDate}` | ||
const findLabelDateTime = async (issueNumber) => { | ||
const iterator = github.paginate.iterator(github.rest.issues.listEventsForTimeline, { | ||
owner: ORGANIZATION, | ||
repo: REPOSITORY, | ||
issue_number: issueNumber, | ||
}) | ||
for await (const { data: timelineData } of iterator) { | ||
for (const timelineItem of timelineData) { | ||
if (timelineItem.event === 'labeled' && ROUTED_TO_LABELS.includes(timelineItem.label.name)) { | ||
return timelineItem.created_at | ||
} | ||
} | ||
} | ||
} | ||
const calculateElapsedDays = (createdAt, routedOrClosedAt) => { | ||
return Math.round((new Date(routedOrClosedAt) - new Date(createdAt)) / MS_PER_DAY, 0) | ||
} | ||
const iterator = github.paginate.iterator(github.rest.search.issuesAndPullRequests, { | ||
q: query, | ||
per_page: 100, | ||
}) | ||
for await (const { data } of iterator) { | ||
for (const issue of data) { | ||
let routedOrClosedAt | ||
if (!issue.pull_request) { | ||
const routedLabel = issue.labels.find((label) => ROUTED_TO_LABELS.includes(label.name)) | ||
if (routedLabel) { | ||
routedOrClosedAt = await findLabelDateTime(issue.number) | ||
} else if (issue.state === 'closed') { | ||
routedOrClosedAt = issue.closed_at | ||
} | ||
let elapsedDays | ||
if (routedOrClosedAt) { | ||
elapsedDays = calculateElapsedDays(issue.created_at, routedOrClosedAt) | ||
} | ||
issues.push({ | ||
number: issue.number, | ||
title: issue.title, | ||
state: issue.state, | ||
url: issue.html_url, | ||
createdAt: issue.created_at, | ||
routedOrClosedAt, | ||
elapsedDays, | ||
}) | ||
} | ||
} | ||
} | ||
const issuesRoutedOrClosedIn7Days = issues.filter((issue) => issue.elapsedDays <= 7).length | ||
const percentage = Number(issues.length > 0 ? issuesRoutedOrClosedIn7Days / issues.length : 0).toLocaleString(undefined, { style: 'percent', minimumFractionDigits: 2 }) | ||
console.log(`Triage Metrics (${dateRange.startDate} - ${dateRange.endDate})`) | ||
console.log('Total issues:', issues.length) | ||
console.log(`Issues routed/closed within 7 days: ${issuesRoutedOrClosedIn7Days} (${percentage})`) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.