MCPcopy Create free account
hub / github.com/github/gh-aw / buildMissingIssueHandler

Function buildMissingIssueHandler

actions/setup/js/missing_issue_helpers.cjs:31–232  ·  view source on GitHub ↗

* Build a shared handler factory for missing issue handlers. * Encapsulates the common search-or-create issue pipeline, differing only in * template paths, item field names, and item renderers. * * @param {Object} options * @param {string} options.handlerType - Handler type identifier used in l

(options)

Source from the content-addressed store, hash-verified

29 * @returns {HandlerFactoryFunction}
30 */
31function buildMissingIssueHandler(options) {
32 const { handlerType, defaultTitlePrefix, itemsField, templatePath, templateListKey, buildCommentHeader, renderCommentItem, renderIssueItem, defaultLabels = [] } = options;
33
34 return async function main(config = {}) {
35 // Extract configuration
36 // create_issue: templatable boolean — default true.
37 // Accepts: literal boolean (true/false), string 'true'/'false', or a GitHub Actions
38 // expression (e.g. '${{ inputs.create-incomplete-issue }}'). Expressions are evaluated
39 // by GitHub Actions before this handler runs, so config.create_issue holds the
40 // resolved boolean or string value when the handler executes.
41 const createIssue = parseBoolTemplatable(config.create_issue, true);
42 const titlePrefix = config.title_prefix || defaultTitlePrefix;
43 const userLabels = config.labels ? (Array.isArray(config.labels) ? config.labels : config.labels.split(",")).map(label => String(label).trim()).filter(label => label) : [];
44 const envLabels = [...new Set([...defaultLabels, ...userLabels])];
45 const maxCount = config.max || 1; // Default to 1 to create only one issue per workflow run
46
47 core.info(`Title prefix: ${titlePrefix}`);
48 if (envLabels.length > 0) {
49 core.info(`Default labels: ${envLabels.join(", ")}`);
50 }
51 core.info(`Max count: ${maxCount}`);
52
53 // Track how many items we've processed for max limit
54 let processedCount = 0;
55
56 // Track created/updated issues
57 const processedIssues = [];
58
59 /**
60 * Create or update an issue for the missing items
61 * @param {string} workflowName - Name of the workflow
62 * @param {string} workflowSource - Source path of the workflow
63 * @param {string} workflowSourceURL - URL to the workflow source
64 * @param {string} runUrl - URL to the workflow run
65 * @param {Array<Object>} items - Array of missing item objects
66 * @returns {Promise<Object>} Result with success/error status
67 */
68 async function createOrUpdateIssue(workflowName, workflowSource, workflowSourceURL, runUrl, items) {
69 const { owner, repo } = context.repo;
70
71 // Create issue title
72 const issueTitle = `${titlePrefix} ${workflowName}`;
73
74 core.info(`Checking for existing issue with title: "${issueTitle}"`);
75
76 // Search for existing open issue with this title
77 const searchQuery = `repo:${owner}/${repo} is:issue is:open in:title "${issueTitle}"`;
78
79 try {
80 const searchResult = await github.rest.search.issuesAndPullRequests({
81 q: searchQuery,
82 per_page: 1,
83 });
84
85 if (searchResult.data.total_count > 0) {
86 // Issue exists, add a comment
87 const existingIssue = searchResult.data.items[0];
88 core.info(`Found existing issue #${existingIssue.number}: ${existingIssue.html_url}`);

Calls 2

parseBoolTemplatableFunction · 0.85
createOrUpdateIssueFunction · 0.85

Tested by

no test coverage detected