Skip to content

Get Harmony Job Status step is not robust against intermittent Harmony, Earthdata Login, or connectivity interruptions #17

Get Harmony Job Status step is not robust against intermittent Harmony, Earthdata Login, or connectivity interruptions

Get Harmony Job Status step is not robust against intermittent Harmony, Earthdata Login, or connectivity interruptions #17

# Automate the triage of issues by team as they are labeled with team:<team_name>.
# This workflow will update the status in the main podaac project to "triaged" and add the issue to the corresponding team project if it exists.
# This helps ensure that issues are properly categorized and visible to the right teams without requiring manual triage in the "needs:triage" column.
name: Team Assignment
on:
issues:
types: [labeled]
jobs:
assign-to-team:
runs-on: ubuntu-latest
steps:
- name: Process team label
uses: actions/github-script@v7
with:
github-token: ${{ secrets.PROJECTS_PAT }}
script: |
const label = context.payload.label.name;
const issueNumber = context.payload.issue.number;
// Check if label matches team:<team_name> pattern
const teamMatch = label.match(/^team:(.+)$/);
if (!teamMatch) {
console.log(`Label "${label}" does not match team:<team_name> pattern, skipping`);
return;
}
const teamName = teamMatch[1];
console.log(`Processing team assignment for team: ${teamName}`);
const podaacProjectNumber = 75;
const org = 'podaac';
const repo = context.repo.repo;
// Define reusable GraphQL mutation for updating project status
const updateStatusMutation = `
mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $value: String!) {
updateProjectV2ItemFieldValue(
input: {
projectId: $projectId
itemId: $itemId
fieldId: $fieldId
value: { singleSelectOptionId: $value }
}
) {
projectV2Item {
id
}
}
}
`;
// ========================================
// Step 1: Update status to "triaged" in podaac project
// ========================================
console.log('Step 1: Updating podaac project status to "triaged"...');
// Get the podaac project information
const podaacProjectQuery = `
query($org: String!, $number: Int!) {
organization(login: $org) {
projectV2(number: $number) {
id
fields(first: 20) {
nodes {
... on ProjectV2SingleSelectField {
id
name
options {
id
name
}
}
}
}
}
}
}
`;
const podaacProjectData = await github.graphql(podaacProjectQuery, {
org: org,
number: podaacProjectNumber
});
const podaacProject = podaacProjectData.organization.projectV2;
const podaacStatusField = podaacProject.fields.nodes.find(field => field.name === 'Status');
const triagedOption = podaacStatusField?.options.find(option => option.name === 'triaged');
let podaacProjectItem = null;
let podaacStatusUpdated = false;
if (!triagedOption) {
core.warning('Could not find "triaged" status option in podaac project');
} else {
// Get the issue's project item in podaac project
const issueProjectItemQuery = `
query($org: String!, $repo: String!, $number: Int!) {
repository(owner: $org, name: $repo) {
issue(number: $number) {
projectItems(first: 10) {
nodes {
id
project {
id
number
}
}
}
}
}
}
`;
const issueData = await github.graphql(issueProjectItemQuery, {
org: org,
repo: repo,
number: issueNumber
});
const projectItems = issueData.repository.issue.projectItems.nodes;
podaacProjectItem = projectItems.find(item => item.project.id === podaacProject.id);
if (!podaacProjectItem) {
core.warning('Issue is not in podaac project, cannot update status');
} else {
// Update the status to "triaged"
await github.graphql(updateStatusMutation, {
projectId: podaacProject.id,
itemId: podaacProjectItem.id,
fieldId: podaacStatusField.id,
value: triagedOption.id
});
podaacStatusUpdated = true;
console.log('✅ Successfully updated status to "triaged" in podaac project');
}
}
// ========================================
// Step 2: Add to team project if it exists
// ========================================
console.log(`Step 2: Looking for team project named "${teamName}"...`);
// Search for team project by name
const teamProjectSearchQuery = `
query($org: String!, $searchQuery: String!) {
organization(login: $org) {
projectsV2(first: 20, query: $searchQuery) {
nodes {
id
number
title
fields(first: 20) {
nodes {
... on ProjectV2SingleSelectField {
id
name
options {
id
name
}
}
}
}
}
}
}
}
`;
const teamProjectSearchData = await github.graphql(teamProjectSearchQuery, {
org: org,
searchQuery: teamName
});
const teamProjects = teamProjectSearchData.organization.projectsV2.nodes;
const teamProject = teamProjects.find(p => p.title.toLowerCase() === teamName.toLowerCase());
if (!teamProject) {
console.log(`⚠️ No project found with name "${teamName}", skipping team project assignment`);
core.notice(`No project found for team "${teamName}". If you want the issue added to a team project, create a project named "${teamName}".`);
return;
}
console.log(`Found team project: ${teamProject.title} (number: ${teamProject.number})`);
// Check if issue is already in the team project
const issueWithProjectsQuery = `
query($org: String!, $repo: String!, $number: Int!) {
repository(owner: $org, name: $repo) {
issue(number: $number) {
id
projectItems(first: 20) {
nodes {
id
project {
id
}
}
}
}
}
}
`;
const issueWithProjects = await github.graphql(issueWithProjectsQuery, {
org: org,
repo: repo,
number: issueNumber
});
const issueNodeId = issueWithProjects.repository.issue.id;
const existingTeamProjectItem = issueWithProjects.repository.issue.projectItems.nodes.find(
item => item.project.id === teamProject.id
);
let teamProjectItemId;
let wasAlreadyInProject = false;
if (existingTeamProjectItem) {
// Issue is already in team project
teamProjectItemId = existingTeamProjectItem.id;
wasAlreadyInProject = true;
console.log(`ℹ️ Issue is already in team project "${teamName}"`);
} else {
// Add issue to team project
const addToProjectMutation = `
mutation($projectId: ID!, $contentId: ID!) {
addProjectV2ItemById(input: {
projectId: $projectId
contentId: $contentId
}) {
item {
id
}
}
}
`;
const addResult = await github.graphql(addToProjectMutation, {
projectId: teamProject.id,
contentId: issueNodeId
});
teamProjectItemId = addResult.addProjectV2ItemById.item.id;
console.log(`✅ Successfully added issue to team project "${teamName}"`);
}
// Summary
const summaryItems = [`Processed team label: ${teamName}`];
if (podaacStatusUpdated) {
summaryItems.push(`Updated podaac project status to "triaged"`);
}
if (wasAlreadyInProject) {
summaryItems.push(`Issue was already in team project "${teamName}"`);
} else {
summaryItems.push(`Added issue to team project "${teamName}"`);
}
core.summary
.addHeading(`Team Assignment Complete: ${teamName}`)
.addList(summaryItems)
.write();