Connect the routing logic with the preferences #32
This file contains hidden or 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
| name: Sync Subtask Week from Parent | |
| on: | |
| issues: | |
| types: [opened, edited] | |
| permissions: | |
| issues: write | |
| contents: read | |
| jobs: | |
| sync-iteration: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Sync iteration from parent issue | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.ORG_PROJECT_TOKEN || secrets.GITHUB_TOKEN }} | |
| script: | | |
| const ORG = 'Commute-ai'; | |
| const PROJECT_NUM = 1; // Update with your project number | |
| // Get issue node ID | |
| const issue = await github.rest.issues.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number | |
| }); | |
| const issueNodeId = issue.data.node_id; | |
| // Query 1: Check if this is a subtask and get parent | |
| const checkSubIssueQuery = ` | |
| query($issueId: ID!) { | |
| node(id: $issueId) { | |
| ... on Issue { | |
| parent { | |
| id | |
| number | |
| repository { | |
| owner { | |
| login | |
| } | |
| name | |
| } | |
| } | |
| } | |
| } | |
| } | |
| `; | |
| const subIssueData = await github.graphql(checkSubIssueQuery, { | |
| issueId: issueNodeId, | |
| headers: { | |
| 'GraphQL-Features': 'sub_issues' | |
| } | |
| }); | |
| const parent = subIssueData.node.parent; | |
| if (!parent) { | |
| console.log('⏭️ This issue is not a sub-issue, skipping'); | |
| return; | |
| } | |
| // Verify parent is in .github repo | |
| if (parent.repository.name !== '.github') { | |
| console.log(`⚠️ Parent is in ${parent.repository.name}, expected .github repo`); | |
| return; | |
| } | |
| console.log(`✅ Found parent: ${parent.repository.owner.login}/.github#${parent.number}`); | |
| // Query 2: Get project items for both parent and child | |
| const projectQuery = ` | |
| query($org: String!, $projNum: Int!) { | |
| organization(login: $org) { | |
| projectV2(number: $projNum) { | |
| id | |
| items(first: 100) { | |
| nodes { | |
| id | |
| content { | |
| ... on Issue { | |
| id | |
| number | |
| repository { | |
| name | |
| } | |
| } | |
| } | |
| fieldValues(first: 20) { | |
| nodes { | |
| ... on ProjectV2ItemFieldIterationValue { | |
| title | |
| iterationId | |
| field { | |
| ... on ProjectV2IterationField { | |
| id | |
| name | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| `; | |
| const projectData = await github.graphql(projectQuery, { | |
| org: ORG, | |
| projNum: PROJECT_NUM | |
| }); | |
| const project = projectData.organization.projectV2; | |
| const allItems = project.items.nodes; | |
| // Find parent and child items | |
| const parentItem = allItems.find(item => item.content?.id === parent.id); | |
| const childItem = allItems.find(item => item.content?.id === issueNodeId); | |
| if (!parentItem) { | |
| console.log('❌ Parent issue not in project board'); | |
| return; | |
| } | |
| if (!childItem) { | |
| console.log('❌ Child issue not in project board yet. Add it first.'); | |
| return; | |
| } | |
| // Get parent's iteration | |
| const parentIteration = parentItem.fieldValues.nodes.find( | |
| fv => fv.field?.name === 'Week' && fv.iterationId | |
| ); | |
| if (!parentIteration) { | |
| console.log('❌ Parent has no iteration set'); | |
| return; | |
| } | |
| console.log(`✅ Parent iteration: ${parentIteration.title}`); | |
| // Update child's iteration | |
| const updateMutation = ` | |
| mutation($projId: ID!, $itemId: ID!, $fieldId: ID!, $iterId: String!) { | |
| updateProjectV2ItemFieldValue(input: { | |
| projectId: $projId | |
| itemId: $itemId | |
| fieldId: $fieldId | |
| value: { iterationId: $iterId } | |
| }) { | |
| projectV2Item { | |
| id | |
| } | |
| } | |
| } | |
| `; | |
| await github.graphql(updateMutation, { | |
| projId: project.id, | |
| itemId: childItem.id, | |
| fieldId: parentIteration.field.id, | |
| iterId: parentIteration.iterationId | |
| }); | |
| console.log(`✅ Synced iteration to: ${parentIteration.title}`); |