name: Project automations on: issues: types: - opened - assigned - closed pull_request: types: - opened - closed # map fields with customized labels env: new: New todo: Todo done: Done in_progress: In Progress in_review: In Review permissions: issues: write pull-requests: write contents: read repository-projects: write jobs: issue_opened: name: issue_opened runs-on: ubuntu-latest if: github.event_name == 'issues' && github.event.action == 'opened' steps: - name: Move issue to ${{ env.new }} uses: leonsteinhaeuser/project-beta-automations@v2.1.0 with: gh_token: ${{ secrets.MY_GITHUB_TOKEN }} organization: ghostbsd project_id: 4 resource_node_id: ${{ github.event.issue.node_id }} status_value: ${{ env.new }} issue_assigned: name: issue_assigned runs-on: ubuntu-latest if: github.event_name == 'issues' && github.event.action == 'assigned' steps: - name: Move issue to ${{ env.in_progress }} uses: leonsteinhaeuser/project-beta-automations@v2.1.0 with: gh_token: ${{ secrets.MY_GITHUB_TOKEN }} organization: ghostbsd project_id: 4 resource_node_id: ${{ github.event.issue.node_id }} status_value: ${{ env.in_progress }} pr_opened: name: pr_opened runs-on: ubuntu-latest if: github.event_name == 'pull_request' && github.event.action == 'opened' steps: - name: Move PR to ${{ env.in_review }} uses: leonsteinhaeuser/project-beta-automations@v2.1.0 with: gh_token: ${{ secrets.MY_GITHUB_TOKEN }} organization: ghostbsd project_id: 4 resource_node_id: ${{ github.event.pull_request.node_id }} status_value: ${{ env.in_review }} issue_or_pr_closed: name: issue_or_pr_closed runs-on: ubuntu-latest if: (github.event_name == 'issues' || github.event_name == 'pull_request') && github.event.action == 'closed' steps: - name: Check Close Reason and Update id: close-reason uses: actions/github-script@v6 with: github-token: ${{ secrets.MY_GITHUB_TOKEN }} script: | const issueNumber = context.payload.number; const repo = context.repo; const isIssue = context.eventName === 'issues'; const nodeId = isIssue ? context.payload.issue.node_id : context.payload.pull_request.node_id; // Log context for debugging console.log(`Event: ${context.eventName}, Issue/PR Number: ${issueNumber}`); console.log(`Repo Owner: ${repo.owner}, Repo Name: ${repo.repo}`); console.log(`Node ID: ${nodeId}`); // Validate inputs if (!issueNumber || !repo.owner || !repo.repo) { throw new Error('Missing required context: issueNumber, repo.owner, or repo.repo'); } // Get issue/PR details try { const { data: issue } = await github.rest.issues.get({ owner: repo.owner, repo: repo.repo, issue_number: issueNumber, }); const closeReason = issue.state_reason || 'none'; let statusValue = ''; let labelToAdd = ''; let shouldArchive = false; if (closeReason === 'not_planned') { labelToAdd = 'wontfix'; shouldArchive = true; } else if (closeReason === 'duplicate') { labelToAdd = 'duplicate'; shouldArchive = true; } else if (closeReason === 'completed') { statusValue = process.env.done; } // Set outputs for status update if applicable if (statusValue) { core.setOutput('status_value', statusValue); core.setOutput('node_id', nodeId); } // Add label if applicable if (labelToAdd) { try { await github.rest.issues.addLabels({ owner: repo.owner, repo: repo.repo, issue_number: issueNumber, labels: [labelToAdd], }); } catch (error) { console.log(`Failed to add label ${labelToAdd}: ${error.message}`); } } // Archive the project item if needed (not supported by project-beta-automations) if (shouldArchive) { try { // Fetch project node ID const projectData = await github.graphql(` query($org: String!, $projectNumber: Int!) { organization(login: $org) { projectV2(number: $projectNumber) { id } } } `, { org: 'ghostbsd', projectNumber: 4 }); const projectId = projectData.organization.projectV2.id; console.log(`Project ID: ${projectId}`); // Fetch project items const projectItems = await github.graphql(` query($org: String!, $projectNumber: Int!) { organization(login: $org) { projectV2(number: $projectNumber) { items(first: 100) { nodes { id content { ... on Issue { id } ... on PullRequest { id } } } } } } } `, { org: 'ghostbsd', projectNumber: 4 }); const projectItem = projectItems.organization.projectV2.items.nodes.find( item => item.content.id === nodeId ); if (projectItem) { await github.graphql(` mutation($projectId: ID!, $itemId: ID!) { archiveProjectV2Item(input: { projectId: $projectId, itemId: $itemId }) { item { id } } } `, { projectId: projectId, itemId: projectItem.id }); console.log(`Archived item with node ID ${nodeId} in project 4`); } else { console.log(`Item with node ID ${nodeId} not found in project 4`); } } catch (error) { console.log(`Failed to archive item: ${error.message}`); } } core.setOutput('close_reason', closeReason); } catch (error) { console.log(`Failed to fetch issue/PR: ${error.message}`); throw error; } - name: Move to Project Board if: steps.close-reason.outputs.status_value uses: leonsteinhaeuser/project-beta-automations@v2.1.0 with: gh_token: ${{ secrets.MY_GITHUB_TOKEN }} organization: ghostbsd project_id: 4 resource_node_id: ${{ steps.close-reason.outputs.node_id }} status_value: ${{ steps.close-reason.outputs.status_value }}