Download .github/workflows/label-workstream-rollup.yml from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 6.62 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/.github/workflows/label-workstream-rollup.yml
- Command line
-
hf download hf://SaylorTwift/gemini-cli/.github/workflows/label-workstream-rollup.yml
-
curl -L -o label-workstream-rollup.yml https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/.github/workflows/label-workstream-rollup.yml
6.62 kB
| name: 'Label Workstream Rollup' | |
| on: | |
| issues: | |
| types: ['opened', 'edited', 'reopened'] | |
| schedule: | |
| - cron: '0 * * * *' | |
| workflow_dispatch: | |
| jobs: | |
| labeler: | |
| if: "github.repository == 'google-gemini/gemini-cli'" | |
| runs-on: 'ubuntu-latest' | |
| permissions: | |
| issues: 'write' | |
| steps: | |
| - name: 'Check for Parent Workstream and Apply Label' | |
| uses: 'actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b' # ratchet:actions/github-script@v7 | |
| with: | |
| script: | | |
| const labelToAdd = 'workstream-rollup'; | |
| // Allow-list of parent issue URLs | |
| const allowedParentUrls = [ | |
| 'https://github.com/google-gemini/gemini-cli/issues/15374', | |
| 'https://github.com/google-gemini/gemini-cli/issues/15456', | |
| 'https://github.com/google-gemini/gemini-cli/issues/15324', | |
| 'https://github.com/google-gemini/gemini-cli/issues/17202', | |
| 'https://github.com/google-gemini/gemini-cli/issues/17203' | |
| ]; | |
| // Single issue processing (for event triggers) | |
| async function processSingleIssue(owner, repo, number) { | |
| const query = ` | |
| query($owner:String!, $repo:String!, $number:Int!) { | |
| repository(owner:$owner, name:$repo) { | |
| issue(number:$number) { | |
| number | |
| parent { | |
| url | |
| parent { | |
| url | |
| parent { | |
| url | |
| parent { | |
| url | |
| parent { | |
| url | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| `; | |
| try { | |
| const result = await github.graphql(query, { owner, repo, number }); | |
| if (!result || !result.repository || !result.repository.issue) { | |
| console.log(`Issue #${number} not found or data missing.`); | |
| return; | |
| } | |
| const issue = result.repository.issue; | |
| await checkAndLabel(issue, owner, repo); | |
| } catch (error) { | |
| console.error(`Failed to process issue #${number}:`, error); | |
| throw error; // Re-throw to be caught by main execution | |
| } | |
| } | |
| // Bulk processing (for schedule/dispatch) | |
| async function processAllOpenIssues(owner, repo) { | |
| const query = ` | |
| query($owner:String!, $repo:String!, $cursor:String) { | |
| repository(owner:$owner, name:$repo) { | |
| issues(first: 100, states: OPEN, after: $cursor) { | |
| pageInfo { | |
| hasNextPage | |
| endCursor | |
| } | |
| nodes { | |
| number | |
| parent { | |
| url | |
| parent { | |
| url | |
| parent { | |
| url | |
| parent { | |
| url | |
| parent { | |
| url | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| `; | |
| let hasNextPage = true; | |
| let cursor = null; | |
| while (hasNextPage) { | |
| try { | |
| const result = await github.graphql(query, { owner, repo, cursor }); | |
| if (!result || !result.repository || !result.repository.issues) { | |
| console.error('Invalid response structure from GitHub API'); | |
| break; | |
| } | |
| const issues = result.repository.issues.nodes || []; | |
| console.log(`Processing batch of ${issues.length} issues...`); | |
| for (const issue of issues) { | |
| await checkAndLabel(issue, owner, repo); | |
| } | |
| hasNextPage = result.repository.issues.pageInfo.hasNextPage; | |
| cursor = result.repository.issues.pageInfo.endCursor; | |
| } catch (error) { | |
| console.error('Failed to fetch issues batch:', error); | |
| throw error; // Re-throw to be caught by main execution | |
| } | |
| } | |
| } | |
| async function checkAndLabel(issue, owner, repo) { | |
| if (!issue || !issue.parent) return; | |
| let currentParent = issue.parent; | |
| let tracedParents = []; | |
| let matched = false; | |
| while (currentParent) { | |
| tracedParents.push(currentParent.url); | |
| if (allowedParentUrls.includes(currentParent.url)) { | |
| console.log(`SUCCESS: Issue #${issue.number} is a descendant of ${currentParent.url}. Trace: ${tracedParents.join(' -> ')}. Adding label.`); | |
| await github.rest.issues.addLabels({ | |
| owner, | |
| repo, | |
| issue_number: issue.number, | |
| labels: [labelToAdd] | |
| }); | |
| matched = true; | |
| break; | |
| } | |
| currentParent = currentParent.parent; | |
| } | |
| if (!matched && context.eventName === 'issues') { | |
| console.log(`Issue #${issue.number} did not match any allowed workstreams. Trace: ${tracedParents.join(' -> ') || 'None'}.`); | |
| } | |
| } | |
| // Main execution | |
| try { | |
| if (context.eventName === 'issues') { | |
| console.log(`Processing single issue #${context.payload.issue.number}...`); | |
| await processSingleIssue(context.repo.owner, context.repo.repo, context.payload.issue.number); | |
| } else { | |
| console.log(`Running for event: ${context.eventName}. Processing all open issues...`); | |
| await processAllOpenIssues(context.repo.owner, context.repo.repo); | |
| } | |
| } catch (error) { | |
| core.setFailed(`Workflow failed: ${error.message}`); | |
| } | |