diff --git a/.github/actions/forward-project-field.mjs b/.github/actions/forward-project-field.mjs deleted file mode 100644 index 33f4cb3..0000000 --- a/.github/actions/forward-project-field.mjs +++ /dev/null @@ -1,244 +0,0 @@ -import { Octokit } from "@octokit/action"; - -const octokit = new Octokit(); - -const headers = { "GraphQL-Features": "projects_next_graphql" } - -const REPO_OWNER = process.env.REPO_OWNER; -const REPO_NAME = process.env.REPO_NAME; -const ISSUE_URL = process.env.ISSUE_URL; -const ISSUE_NUMBER = parseInt(process.env.ISSUE_NUMBER); -const PROJECT_ID = process.env.PROJECT_ID; -const FIELD_ID = process.env.FIELD_ID; -const FIELD_NAME = process.env.FIELD_NAME; - -const visitedIssueUrls = new Set(); - -async function queryFieldValue(repoOwner, repoName, issueNumber, fieldName) { - const query = `query ($owner: String!, $repo: String!, $issueNumber: Int!, $fieldName: String!) { - repository(owner: $owner, name: $repo) { - issue(number: $issueNumber) { - projectItems(first: 100) { - edges { - node { - id - fieldValueByName(name: $fieldName) { - ... on ProjectV2ItemFieldSingleSelectValue { - optionId - name - field { - ... on ProjectV2SingleSelectField { - id - } - } - } - } - project { - id - } - } - } - } - } - } - }`; - - const parameters = { - owner: repoOwner, - repo: repoName, - issueNumber: issueNumber, - fieldName: fieldName, - headers - }; - - const result = await octokit.graphql(query, parameters); - - return result.repository.issue.projectItems.edges; -} - -function determineFieldValue(projectItems, projectId, fieldId) { - for (const item of projectItems) { - if (item.node.project.id == projectId && item.node.fieldValueByName && item.node.fieldValueByName.field.id == fieldId) { - return { name: item.node.fieldValueByName.name, id: item.node.fieldValueByName.optionId }; - } - } - - return {} -} - -async function setFieldValueOnTrackedIssues(repoOwner, repoName, issueUrl, issueNumber, projectId, fieldId, fieldName, fieldValue) { - // Avoid infinite loop - - if (visitedIssueUrls.has(issueUrl)) { - return; - } - visitedIssueUrls.add(issueUrl); - - // Make sure this is actually an issue - - if (issueUrl.indexOf("/issues/") < 0) { - return; - } - - // Get tracked issues - - console.log(`Querying tracked issues of ${issueUrl}`); - const trackedIssues = await queryTrackedIssues(repoOwner, repoName, issueNumber); - - if (!trackedIssues || trackedIssues.length == 0) { - console.log("Aborting because issue has no tracked issues"); - return; - } - - console.log(trackedIssues.map(issue => issue.node.url)); - - // Set field values - - for (const issue of trackedIssues) { - const trackedIssueId = issue.node.id; - const trackedIssueUrl = issue.node.url; - const trackedIssueNumber = issue.node.number; - const trackedRepoOwner = issue.node.repository.owner.login; - const trackedRepoName = issue.node.repository.name; - - // Get project item or add one if needed - - let itemId = issue.node.projectItems.edges.find(item => item.node.project.id == projectId)?.node?.id; - - if (!itemId) { - console.log(`Adding ${trackedIssueUrl} to project`); - itemId = await addItemToProject(projectId, trackedIssueId); - } - - // Set field value - - console.log(`Setting value "${fieldValue.name}" for field "${fieldName}" of ${trackedIssueUrl}`); - mutateFieldValue(projectId, itemId, fieldId, fieldValue.id); - - // Recurse - - await setFieldValueOnTrackedIssues(trackedRepoOwner, trackedRepoName, trackedIssueUrl, trackedIssueNumber, projectId, fieldId, fieldName, fieldValue); - } -} - -async function queryTrackedIssues(repoOwner, repoName, issueNumber) { - const query = `query ($owner: String!, $repo: String!, $issueNumber: Int!) { - repository(owner: $owner, name: $repo) { - issue(number: $issueNumber) { - trackedIssues(first: 100) { - edges { - node { - projectItems(first: 100) { - edges { - node { - id - project { - id - } - } - } - } - id - url - number - repository { - name - owner { - login - } - } - } - } - } - } - } - }`; - - const parameters = { - owner: repoOwner, - repo: repoName, - issueNumber: issueNumber, - headers - }; - - const result = await octokit.graphql(query, parameters); - - return result.repository.issue.trackedIssues.edges; -} - -async function addItemToProject(projectId, contentId) { - const mutation = `mutation ($projectId: ID!, $contentId: ID!) { - addProjectV2ItemById(input: {projectId: $projectId contentId: $contentId}) { - item { - id - } - } - }`; - - const parameters = { - projectId: projectId, - contentId: contentId, - headers - }; - - const result = await octokit.graphql(mutation, parameters); - - return result.addProjectV2ItemById.item.id; -} - -async function mutateFieldValue(projectId, itemId, fieldId, fieldValueId) { - const mutation = `mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) { - updateProjectV2ItemFieldValue( - input: { - projectId: $projectId - itemId: $itemId - fieldId: $fieldId - value: { - singleSelectOptionId: $optionId - } - } - ) { - projectV2Item { - id - } - } - }`; - - const parameters = { - projectId: projectId, - itemId: itemId, - fieldId: fieldId, - optionId: fieldValueId, - headers - }; - - await octokit.graphql(mutation, parameters); -} - -(async function main() { - // Get project items - - console.log(`Querying value for field "${FIELD_NAME}" of ${ISSUE_URL}`); - const projectItems = await queryFieldValue(REPO_OWNER, REPO_NAME, ISSUE_NUMBER, FIELD_NAME); - - if (!projectItems) { - console.log("Aborting because issue is not part of any projects"); - return; - } - - // Determine field value - - fieldValue = determineFieldValue(projectItems, PROJECT_ID, FIELD_ID); - - if (!fieldValue.name || !fieldValue.id) { - console.log("Aborting because issue is not part of the correct project"); - return; - } - - console.log(`Determined field value "${fieldValue.name}" (${fieldValue.id})`); - - // Set field value on tracked issues - - await setFieldValueOnTrackedIssues(REPO_OWNER, REPO_NAME, ISSUE_URL, ISSUE_NUMBER, PROJECT_ID, FIELD_ID, FIELD_NAME, fieldValue); - -})(); diff --git a/.github/workflows/triage-move-labelled.yml b/.github/workflows/triage-move-labelled.yml index 586b477..7561feb 100644 --- a/.github/workflows/triage-move-labelled.yml +++ b/.github/workflows/triage-move-labelled.yml @@ -5,58 +5,6 @@ on: types: [labeled] jobs: - apply_Z-Labs_label: - name: Add Z-Labs label for features behind labs flags - runs-on: ubuntu-latest - if: > - contains(github.event.issue.labels.*.name, 'A-Maths') || - contains(github.event.issue.labels.*.name, 'A-Message-Pinning') || - contains(github.event.issue.labels.*.name, 'A-Threads') || - contains(github.event.issue.labels.*.name, 'A-Polls') || - contains(github.event.issue.labels.*.name, 'A-Location-Sharing') || - contains(github.event.issue.labels.*.name, 'A-Message-Bubbles') || - contains(github.event.issue.labels.*.name, 'Z-IA') || - contains(github.event.issue.labels.*.name, 'A-Themes-Custom') || - contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') || - contains(github.event.issue.labels.*.name, 'A-Tags') - steps: - - uses: actions/github-script@v5 - with: - script: | - github.rest.issues.addLabels({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - labels: ['Z-Labs'] - }) - - add_design_issues_to_project: - name: X-Needs-Design to Design project board - runs-on: ubuntu-latest - if: > - contains(github.event.issue.labels.*.name, 'X-Needs-Design') && - (contains(github.event.issue.labels.*.name, 'S-Critical') && - (contains(github.event.issue.labels.*.name, 'O-Frequent') || - contains(github.event.issue.labels.*.name, 'O-Occasional')) || - contains(github.event.issue.labels.*.name, 'S-Major') && - contains(github.event.issue.labels.*.name, 'O-Frequent') || - contains(github.event.issue.labels.*.name, 'A11y')) - steps: - - uses: actions/add-to-project@main - with: - project-url: https://github.com/orgs/element-hq/projects/18 - github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} - - add_product_issues: - name: X-Needs-Product to Design project board - runs-on: ubuntu-latest - if: > - contains(github.event.issue.labels.*.name, 'X-Needs-Product') - steps: - - uses: actions/add-to-project@main - with: - project-url: https://github.com/orgs/element-hq/projects/28 - github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} ex_platform: name: Add labelled issues to EX platform project @@ -77,28 +25,5 @@ jobs: steps: - uses: actions/add-to-project@main with: - project-url: https://github.com/orgs/element-hq/projects/41 - github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} - - qa: - name: Add labelled issues to QA project - runs-on: ubuntu-latest - if: > - contains(github.event.issue.labels.*.name, 'Team: QA') || - contains(github.event.issue.labels.*.name, 'X-Needs-Signoff') - steps: - - uses: actions/add-to-project@main - with: - project-url: https://github.com/orgs/element-hq/projects/69 - github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} - - signoff: - name: Add labelled issues to signoff project - runs-on: ubuntu-latest - if: > - contains(github.event.issue.labels.*.name, 'X-Needs-Signoff') - steps: - - uses: actions/add-to-project@main - with: - project-url: https://github.com/orgs/element-hq/projects/89 + project-url: https://github.com/orgs/element-hq/projects/139 github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} diff --git a/.github/workflows/triage-move-unlabelled.yml b/.github/workflows/triage-move-unlabelled.yml deleted file mode 100644 index 89b7b77..0000000 --- a/.github/workflows/triage-move-unlabelled.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Move unlabelled from needs info columns to triaged - -on: - issues: - types: [unlabeled] - -jobs: - remove_Z-Labs_label: - name: Remove Z-Labs label when features behind labs flags are removed - runs-on: ubuntu-latest - if: > - !(contains(github.event.issue.labels.*.name, 'A-Maths') || - contains(github.event.issue.labels.*.name, 'A-Message-Pinning') || - contains(github.event.issue.labels.*.name, 'A-Threads') || - contains(github.event.issue.labels.*.name, 'A-Polls') || - contains(github.event.issue.labels.*.name, 'A-Location-Sharing') || - contains(github.event.issue.labels.*.name, 'A-Message-Bubbles') || - contains(github.event.issue.labels.*.name, 'Z-IA') || - contains(github.event.issue.labels.*.name, 'A-Themes-Custom') || - contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') || - contains(github.event.issue.labels.*.name, 'A-Tags')) && - contains(github.event.issue.labels.*.name, 'Z-Labs') - steps: - - uses: actions/github-script@v5 - with: - script: | - github.rest.issues.removeLabel({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - name: ['Z-Labs'] - }) diff --git a/.github/workflows/x-plorers-epic-forwarding.yml b/.github/workflows/x-plorers-epic-forwarding.yml deleted file mode 100644 index 9812b6b..0000000 --- a/.github/workflows/x-plorers-epic-forwarding.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Forward epic field value into tracked issues - -on: - issues: - types: [edited] - -jobs: - forward_epic_field_value: - name: Forward epic field value into tracked issues - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 18 - - run: npm install @octokit/action - - run: node .github/actions/forward-project-field.mjs - env: - GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }} - REPO_OWNER: ${{ github.event.repository.owner.login }} - REPO_NAME: ${{ github.event.repository.name }} - ISSUE_URL: ${{ github.event.issue.html_url }} - ISSUE_NUMBER: ${{ github.event.issue.number }} - PROJECT_ID: "PVT_kwDOAM0swc4ALoFY" - FIELD_ID: "PVTSSF_lADOAM0swc4ALoFYzgJAimw" - FIELD_NAME: Epic