From 8ec5549631efe871121e7bfae090448f5af8cae4 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 18:04:41 +0000 Subject: [PATCH 01/31] basic action --- .github/workflows/generate-weekly-report.yml | 76 ++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 .github/workflows/generate-weekly-report.yml diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml new file mode 100644 index 000000000000..044a22f3abb0 --- /dev/null +++ b/.github/workflows/generate-weekly-report.yml @@ -0,0 +1,76 @@ +# This action generates a weekly report as a github issue +# More details in https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24672 + +name: 'Generate Weekly Report' +on: + workflow_dispatch: + + +jobs: + get_issues: + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + script: | + async function getIssues(github, queryParams, filterPrs = true) { + let allIssues = []; + try { + while (true) { + const response = await github.issues.listForRepo(queryParams); + // filter out pull requests + const issues = filterPrs ? response.data.filter(issue => !issue.pull_request) : response.data; + allIssues = allIssues.concat(issues); + + // Check the 'link' header to see if there are more pages + const linkHeader = response.headers.link; + if (!linkHeader || !linkHeader.includes('rel="next"')) { + break; + } + + queryParams.page++; + } + return allIssues; + } catch (error) { + console.error('Error fetching issues:', error); + return []; + } + } + + function genLookbackDates() { + const now = new Date(); + const midnightYesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1); + const sevenDaysAgo = new Date(midnightYesterday); + sevenDaysAgo.setDate(midnightYesterday.getDate() - 7); + return { sevenDaysAgo, midnightYesterday }; + } + + function filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }) { + const createdAt = new Date(issue.created_at); + return createdAt >= sevenDaysAgo && createdAt <= midnightYesterday; + } + + async function getNewIssues(github) { + const { sevenDaysAgo, midnightYesterday} = genLookbackDates(); + const queryParams = { + owner: 'open-telemetry', + repo: 'opentelemetry-collector-contrib', + state: 'all', // To get both open and closed issues + per_page: 100, // Number of items per page (maximum allowed) + page: 1, // Start with page 1 + since: sevenDaysAgo.toISOString(), + }; + + try { + const allIssues = await getIssues(github, queryParams) + const filteredIssues = allIssues.filter(issue => filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday })); + return filteredIssues; + } catch (error) { + console.error('Error fetching issues:', error); + return []; + } + } + + const issuesNew = await getNewIssues(github); + console.log(JSON.stringify(issuesNew, null, 2)); + \ No newline at end of file From ce431baf2b36f8a7a234b08d6262ad7a6ee98c50 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 18:09:06 +0000 Subject: [PATCH 02/31] chore: disable all auto gh action --- .github/workflows/build-and-test-windows.yml | 6 +++--- .github/workflows/build-and-test.yml | 8 ++++---- .github/workflows/check-links.yaml | 4 ++-- .github/workflows/codeql-analysis.yml | 4 ++-- .github/workflows/e2e-tests.yml | 6 +++--- .github/workflows/prometheus-compliance-tests.yml | 4 ++-- .github/workflows/telemetrygen.yml | 4 ++-- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-and-test-windows.yml b/.github/workflows/build-and-test-windows.yml index 7a1e0ee98865..f548974eaaac 100644 --- a/.github/workflows/build-and-test-windows.yml +++ b/.github/workflows/build-and-test-windows.yml @@ -1,9 +1,9 @@ name: build-and-test-windows on: push: - branches: - - 'main' - - 'releases/**' + # branches: + # - 'main' + # - 'releases/**' tags: - 'v[0-9]+.[0-9]+.[0-9]+*' pull_request: diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index b46671355cdf..6db868ac2104 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -1,9 +1,9 @@ name: build-and-test on: - push: - branches: [ main ] - tags: - - 'v[0-9]+.[0-9]+.[0-9]+*' + # push: + # branches: [ main ] + # tags: + # - 'v[0-9]+.[0-9]+.[0-9]+*' pull_request: env: TEST_RESULTS: testbed/tests/results/junit/results.xml diff --git a/.github/workflows/check-links.yaml b/.github/workflows/check-links.yaml index 83817d99f1f5..d5e4c29f2bef 100644 --- a/.github/workflows/check-links.yaml +++ b/.github/workflows/check-links.yaml @@ -1,7 +1,7 @@ name: check-links on: - push: - branches: [ main ] + # push: + # branches: [ main ] pull_request: # Do not cancel this workflow on main. See https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/16616 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6a734c9a5f66..ca1c8ed15e82 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,8 +1,8 @@ name: "CodeQL Analysis" on: - push: - branches: [main] + # push: + # branches: [main] jobs: CodeQL-Build: diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 99a56d2346df..c7ff0dce95b3 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -1,9 +1,9 @@ name: e2e-tests on: - push: - branches: - - main + # push: + # branches: + # - main tags: - 'v[0-9]+.[0-9]+.[0-9]+*' pull_request: diff --git a/.github/workflows/prometheus-compliance-tests.yml b/.github/workflows/prometheus-compliance-tests.yml index 8a31fcd98634..c191a345b12d 100644 --- a/.github/workflows/prometheus-compliance-tests.yml +++ b/.github/workflows/prometheus-compliance-tests.yml @@ -1,7 +1,7 @@ name: prometheus-compliance-tests on: - push: - branches: [ main ] + # push: + # branches: [ main ] tags: - 'v[0-9]+.[0-9]+.[0-9]+*' pull_request: diff --git a/.github/workflows/telemetrygen.yml b/.github/workflows/telemetrygen.yml index 94938bccccb8..01ce0fb134af 100644 --- a/.github/workflows/telemetrygen.yml +++ b/.github/workflows/telemetrygen.yml @@ -1,7 +1,7 @@ name: telemetrygen on: - push: - branches: [ main ] + # push: + # branches: [ main ] tags: - 'v[0-9]+.[0-9]+.[0-9]+*' pull_request: From 647de3bed9341aa1482ddd6a53447ac7be21015c Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 18:12:40 +0000 Subject: [PATCH 03/31] test: add rest param --- .github/workflows/generate-weekly-report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml index 044a22f3abb0..432676fcfa15 100644 --- a/.github/workflows/generate-weekly-report.yml +++ b/.github/workflows/generate-weekly-report.yml @@ -71,6 +71,6 @@ jobs: } } - const issuesNew = await getNewIssues(github); + const issuesNew = await getNewIssues(github.rest); console.log(JSON.stringify(issuesNew, null, 2)); \ No newline at end of file From 30d4fa44173f9d1c020f103425226d0770b69a46 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 18:16:12 +0000 Subject: [PATCH 04/31] run on push --- .github/workflows/generate-weekly-report.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml index 432676fcfa15..365f34f64647 100644 --- a/.github/workflows/generate-weekly-report.yml +++ b/.github/workflows/generate-weekly-report.yml @@ -4,7 +4,8 @@ name: 'Generate Weekly Report' on: workflow_dispatch: - + push: + branches: [ main ] jobs: get_issues: @@ -12,6 +13,7 @@ jobs: steps: - uses: actions/github-script@v6 with: + retries: 3 script: | async function getIssues(github, queryParams, filterPrs = true) { let allIssues = []; From b45a980bde54f3e51857f722d127731acf7ef474 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 18:45:22 +0000 Subject: [PATCH 05/31] get all issue stats --- .github/workflows/generate-weekly-report.yml | 97 +++++++++++++++++++- 1 file changed, 94 insertions(+), 3 deletions(-) diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml index 365f34f64647..50c298fd25ad 100644 --- a/.github/workflows/generate-weekly-report.yml +++ b/.github/workflows/generate-weekly-report.yml @@ -12,6 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/github-script@v6 + id: get-issues with: retries: 3 script: | @@ -72,7 +73,97 @@ jobs: return []; } } - + + async function getTargetLabelIssues(octokit, labels, filterPrs) { + const queryParams = { + owner: 'open-telemetry', + repo: 'opentelemetry-collector-contrib', + state: 'open', + per_page: 100, // Number of items per page (maximum allowed) + page: 1, // Start with page 1 + labels + }; + try { + const allIssues = await getIssues(octokit, queryParams, filterPrs) + return allIssues; + } catch (error) { + console.error('Error fetching issues:', error); + return []; + } + } + + const targetLabels = { + "needs triage": { + filterPrs: true, + alias: "issuesTriage", + }, + "ready to merge": { + filterPrs: false, + alias: "issuesReadyToMerge", + }, + "Sponsor Needed": { + filterPrs: true, + alias: "issuesSponsorNeeded", + }, + }; + const issuesNew = await getNewIssues(github.rest); - console.log(JSON.stringify(issuesNew, null, 2)); - \ No newline at end of file + const issuesWithLabels = {}; + for (const lbl of Object.keys(targetLabels)) { + const filterPrs = targetLabels[lbl].filterPrs; + const resp = await getTargetLabelIssues(github.rest, lbl, filterPrs); + issuesWithLabels[lbl] = resp; + } + + // tally results + const stats = { + issuesNew: { + count: 0, + data: [] + }, + issuesTriage: { + count: 0, + data: [] + }, + issuesReadyToMerge: { + count: 0, + data: [] + }, + issuesSponsorNeeded: { + count: 0, + data: [] + }, + issuesNewSponsorNeeded: { + count: 0, + data: [] + }, + } + + // add new issues + issuesNew.forEach(issue => { + stats.issuesNew.count++; + const { url, title, number } = issue; + stats.issuesNew.data.push({ url, title, number }); + }); + + // add issues with labels + for (const lbl of Object.keys(targetLabels)) { + const alias = targetLabels[lbl].alias; + stats[alias].count = issuesWithLabels[lbl].length; + stats[alias].data = issuesWithLabels[lbl].map(issue => { + const { url, title, number } = issue; + return { url, title, number }; + }) + } + + // add new issues with sponsor needed label + const {sevenDaysAgo, midnightYesterday} = genLookbackDates(); + const sponsorNeededIssues = issuesWithLabels["Sponsor Needed"].filter(issue => filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday })); + sponsorNeededIssues.forEach(issue => { + stats.issuesNewSponsorNeeded.count++; + const { url, title, number } = issue; + stats.issuesNewSponsorNeeded.data.push({ url, title, number }); + }); + return stats; + - name: Get result + run: echo "${{steps.get-issues.outputs.result}}" \ No newline at end of file From b39c660903da773d26c67e4cdae8199361e8b77e Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 19:40:45 +0000 Subject: [PATCH 06/31] generate report --- .github/workflows/generate-weekly-report.yml | 186 +++++++++++-------- 1 file changed, 113 insertions(+), 73 deletions(-) diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml index 50c298fd25ad..33f6ad18ab2a 100644 --- a/.github/workflows/generate-weekly-report.yml +++ b/.github/workflows/generate-weekly-report.yml @@ -11,6 +11,7 @@ jobs: get_issues: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v3 - uses: actions/github-script@v6 id: get-issues with: @@ -54,7 +55,7 @@ jobs: } async function getNewIssues(github) { - const { sevenDaysAgo, midnightYesterday} = genLookbackDates(); + const { sevenDaysAgo, midnightYesterday } = genLookbackDates(); const queryParams = { owner: 'open-telemetry', repo: 'opentelemetry-collector-contrib', @@ -92,78 +93,117 @@ jobs: } } - const targetLabels = { - "needs triage": { - filterPrs: true, - alias: "issuesTriage", - }, - "ready to merge": { - filterPrs: false, - alias: "issuesReadyToMerge", - }, - "Sponsor Needed": { - filterPrs: true, - alias: "issuesSponsorNeeded", - }, - }; - - const issuesNew = await getNewIssues(github.rest); - const issuesWithLabels = {}; - for (const lbl of Object.keys(targetLabels)) { - const filterPrs = targetLabels[lbl].filterPrs; - const resp = await getTargetLabelIssues(github.rest, lbl, filterPrs); - issuesWithLabels[lbl] = resp; + async function getIssuesData(github) { + const targetLabels = { + "needs triage": { + filterPrs: true, + alias: "issuesTriage", + }, + "ready to merge": { + filterPrs: false, + alias: "issuesReadyToMerge", + }, + "Sponsor Needed": { + filterPrs: true, + alias: "issuesSponsorNeeded", + }, + }; + + const issuesNew = await getNewIssues(github.rest); + const issuesWithLabels = {}; + for (const lbl of Object.keys(targetLabels)) { + const filterPrs = targetLabels[lbl].filterPrs; + const resp = await getTargetLabelIssues(github.rest, lbl, filterPrs); + issuesWithLabels[lbl] = resp; + } + + // tally results + const stats = { + issuesNew: { + title: "New issues", + count: 0, + data: [] + }, + issuesTriage: { + title: "Issues needing triage", + count: 0, + data: [] + }, + issuesReadyToMerge: { + title: "Issues ready to merge", + count: 0, + data: [] + }, + issuesSponsorNeeded: { + title: "Issues needing sponsorship", + count: 0, + data: [] + }, + issuesNewSponsorNeeded: { + title: "New issues needing sponsorship", + count: 0, + data: [] + }, + } + + // add new issues + issuesNew.forEach(issue => { + stats.issuesNew.count++; + const { url, title, number } = issue; + stats.issuesNew.data.push({ url, title, number }); + }); + + // add issues with labels + for (const lbl of Object.keys(targetLabels)) { + const alias = targetLabels[lbl].alias; + stats[alias].count = issuesWithLabels[lbl].length; + stats[alias].data = issuesWithLabels[lbl].map(issue => { + const { url, title, number } = issue; + return { url, title, number }; + }) + } + + // add new issues with sponsor needed label + const { sevenDaysAgo, midnightYesterday } = genLookbackDates(); + const sponsorNeededIssues = issuesWithLabels["Sponsor Needed"].filter(issue => filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday })); + sponsorNeededIssues.forEach(issue => { + stats.issuesNewSponsorNeeded.count++; + const { url, title, number } = issue; + stats.issuesNewSponsorNeeded.data.push({ url, title, number }); + }); + return stats } - - // tally results - const stats = { - issuesNew: { - count: 0, - data: [] - }, - issuesTriage: { - count: 0, - data: [] - }, - issuesReadyToMerge: { - count: 0, - data: [] - }, - issuesSponsorNeeded: { - count: 0, - data: [] - }, - issuesNewSponsorNeeded: { - count: 0, - data: [] - }, + + function generateReport({issuesData}) { + const out = ['
    ']; + + for (const lbl of Object.keys(issuesData)) { + const section = []; + const title = lbl; + const {count, data} = issuesData[lbl]; + section.push(`
  • ${title}: ${count}`); + section.push(`
    + Issues +
      + ${data.map((issue) => { + const {url, title, number} = issue; + return `
    • #${number} ${title}
    • `; + }).join('\n')} +
    +
    `); + section.push('
  • '); + out.push(section.join('\n')); + } + + out.push('
'); + const report = out.join('\n'); + return report; } - - // add new issues - issuesNew.forEach(issue => { - stats.issuesNew.count++; - const { url, title, number } = issue; - stats.issuesNew.data.push({ url, title, number }); - }); - - // add issues with labels - for (const lbl of Object.keys(targetLabels)) { - const alias = targetLabels[lbl].alias; - stats[alias].count = issuesWithLabels[lbl].length; - stats[alias].data = issuesWithLabels[lbl].map(issue => { - const { url, title, number } = issue; - return { url, title, number }; - }) + + async function main({ github, context }) { + const issuesData = await getIssuesData(github) + const report = generateReport({issuesData}) + console.log(report) } - - // add new issues with sponsor needed label - const {sevenDaysAgo, midnightYesterday} = genLookbackDates(); - const sponsorNeededIssues = issuesWithLabels["Sponsor Needed"].filter(issue => filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday })); - sponsorNeededIssues.forEach(issue => { - stats.issuesNewSponsorNeeded.count++; - const { url, title, number } = issue; - stats.issuesNewSponsorNeeded.data.push({ url, title, number }); - }); - return stats; - - name: Get result - run: echo "${{steps.get-issues.outputs.result}}" \ No newline at end of file + + await main({github, context}) \ No newline at end of file From c14d4a9f55403fff4d4ca32e49867b68a1e878e2 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 19:42:19 +0000 Subject: [PATCH 07/31] revert: disable load tests --- .github/workflows/load-tests.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/load-tests.yml b/.github/workflows/load-tests.yml index 466dfc3071e2..be60d7333351 100644 --- a/.github/workflows/load-tests.yml +++ b/.github/workflows/load-tests.yml @@ -1,9 +1,9 @@ name: load-tests on: - push: - branches: [ main ] - tags: - - 'v[0-9]+.[0-9]+.[0-9]+*' + # push: + # branches: [ main ] + # tags: + # - 'v[0-9]+.[0-9]+.[0-9]+*' pull_request: # Do not cancel this workflow on main. See https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/16616 From c78399489085081bc59dab44633d60212993f055 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 19:48:18 +0000 Subject: [PATCH 08/31] better title label --- .github/workflows/generate-weekly-report.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml index 33f6ad18ab2a..54187292d332 100644 --- a/.github/workflows/generate-weekly-report.yml +++ b/.github/workflows/generate-weekly-report.yml @@ -179,8 +179,7 @@ jobs: for (const lbl of Object.keys(issuesData)) { const section = []; - const title = lbl; - const {count, data} = issuesData[lbl]; + const {count, data, title} = issuesData[lbl]; section.push(`
  • ${title}: ${count}`); section.push(`
    Issues @@ -205,5 +204,5 @@ jobs: const report = generateReport({issuesData}) console.log(report) } - + await main({github, context}) \ No newline at end of file From 2697e16cad85c4b446669e66fae294910b90b31e Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 20:13:29 +0000 Subject: [PATCH 09/31] create an issue --- .github/workflows/generate-weekly-report.yml | 34 ++++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml index 54187292d332..4af39614aa62 100644 --- a/.github/workflows/generate-weekly-report.yml +++ b/.github/workflows/generate-weekly-report.yml @@ -46,7 +46,7 @@ jobs: const midnightYesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1); const sevenDaysAgo = new Date(midnightYesterday); sevenDaysAgo.setDate(midnightYesterday.getDate() - 7); - return { sevenDaysAgo, midnightYesterday }; + return { sevenDaysAgo, midnightYesterday}; } function filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }) { @@ -195,14 +195,42 @@ jobs: } out.push(''); + + // add json data + out.push('\n ## JSON Data'); + out.push(''); + out.push( `
    + Expand +
    +            {
    +              "issuesData": ${JSON.stringify(issuesData, null, 2)}
    +            }
    +            
    +
    `); const report = out.join('\n'); return report; } + async function createIssue({github, lookbackData, report}) { + const title = `Weekly Report: ${lookbackData.sevenDaysAgo.toISOString().slice(0, 10)} - ${lookbackData.midnightYesterday.toISOString().slice(0, 10)}`; + return github.rest.issues.create({ + // TODO: change + owner: "kevinslin", + repo: "opentelemetry-collector-contrib", + title, + body: report, + labels: ["report"] + }) + } + async function main({ github, context }) { + const lookbackData = genLookbackDates(); const issuesData = await getIssuesData(github) const report = generateReport({issuesData}) - console.log(report) + + // const fs = require('fs'); + // const report = fs.readFileSync('./fixtures/report.md', 'utf8') + await createIssue({github, lookbackData, report}); } - + await main({github, context}) \ No newline at end of file From e76d4e239c53bc6884c1c1408b0723d4d325b818 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 21:40:20 +0000 Subject: [PATCH 10/31] Revert "chore: disable all auto gh action" This reverts commit 06def3f0890164bcc2c9ca6fbbc067a482d94997. --- .github/workflows/build-and-test-windows.yml | 6 +++--- .github/workflows/build-and-test.yml | 8 ++++---- .github/workflows/check-links.yaml | 4 ++-- .github/workflows/codeql-analysis.yml | 4 ++-- .github/workflows/e2e-tests.yml | 6 +++--- .github/workflows/prometheus-compliance-tests.yml | 4 ++-- .github/workflows/telemetrygen.yml | 4 ++-- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-and-test-windows.yml b/.github/workflows/build-and-test-windows.yml index f548974eaaac..7a1e0ee98865 100644 --- a/.github/workflows/build-and-test-windows.yml +++ b/.github/workflows/build-and-test-windows.yml @@ -1,9 +1,9 @@ name: build-and-test-windows on: push: - # branches: - # - 'main' - # - 'releases/**' + branches: + - 'main' + - 'releases/**' tags: - 'v[0-9]+.[0-9]+.[0-9]+*' pull_request: diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 6db868ac2104..b46671355cdf 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -1,9 +1,9 @@ name: build-and-test on: - # push: - # branches: [ main ] - # tags: - # - 'v[0-9]+.[0-9]+.[0-9]+*' + push: + branches: [ main ] + tags: + - 'v[0-9]+.[0-9]+.[0-9]+*' pull_request: env: TEST_RESULTS: testbed/tests/results/junit/results.xml diff --git a/.github/workflows/check-links.yaml b/.github/workflows/check-links.yaml index d5e4c29f2bef..83817d99f1f5 100644 --- a/.github/workflows/check-links.yaml +++ b/.github/workflows/check-links.yaml @@ -1,7 +1,7 @@ name: check-links on: - # push: - # branches: [ main ] + push: + branches: [ main ] pull_request: # Do not cancel this workflow on main. See https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/16616 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index ca1c8ed15e82..6a734c9a5f66 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,8 +1,8 @@ name: "CodeQL Analysis" on: - # push: - # branches: [main] + push: + branches: [main] jobs: CodeQL-Build: diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index c7ff0dce95b3..99a56d2346df 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -1,9 +1,9 @@ name: e2e-tests on: - # push: - # branches: - # - main + push: + branches: + - main tags: - 'v[0-9]+.[0-9]+.[0-9]+*' pull_request: diff --git a/.github/workflows/prometheus-compliance-tests.yml b/.github/workflows/prometheus-compliance-tests.yml index c191a345b12d..8a31fcd98634 100644 --- a/.github/workflows/prometheus-compliance-tests.yml +++ b/.github/workflows/prometheus-compliance-tests.yml @@ -1,7 +1,7 @@ name: prometheus-compliance-tests on: - # push: - # branches: [ main ] + push: + branches: [ main ] tags: - 'v[0-9]+.[0-9]+.[0-9]+*' pull_request: diff --git a/.github/workflows/telemetrygen.yml b/.github/workflows/telemetrygen.yml index 01ce0fb134af..94938bccccb8 100644 --- a/.github/workflows/telemetrygen.yml +++ b/.github/workflows/telemetrygen.yml @@ -1,7 +1,7 @@ name: telemetrygen on: - # push: - # branches: [ main ] + push: + branches: [ main ] tags: - 'v[0-9]+.[0-9]+.[0-9]+*' pull_request: From 10592589694a2f4e825ba48ceeac9a140f8278d9 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 21:40:28 +0000 Subject: [PATCH 11/31] Revert "revert: disable load tests" This reverts commit c9419e5349d69977ea0b85103c5a49f705758b3d. --- .github/workflows/load-tests.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/load-tests.yml b/.github/workflows/load-tests.yml index be60d7333351..466dfc3071e2 100644 --- a/.github/workflows/load-tests.yml +++ b/.github/workflows/load-tests.yml @@ -1,9 +1,9 @@ name: load-tests on: - # push: - # branches: [ main ] - # tags: - # - 'v[0-9]+.[0-9]+.[0-9]+*' + push: + branches: [ main ] + tags: + - 'v[0-9]+.[0-9]+.[0-9]+*' pull_request: # Do not cancel this workflow on main. See https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/16616 From 863417569f578eabd22d54c2d61b4f6c6c71b562 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 21:45:23 +0000 Subject: [PATCH 12/31] update workflow branch --- .github/workflows/generate-weekly-report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml index 4af39614aa62..f08e9f44bbc5 100644 --- a/.github/workflows/generate-weekly-report.yml +++ b/.github/workflows/generate-weekly-report.yml @@ -5,7 +5,7 @@ name: 'Generate Weekly Report' on: workflow_dispatch: push: - branches: [ main ] + branches: [ chore/weekly-report-gen ] jobs: get_issues: From 41080fdcfd1d97c8f2b974f2fa7656dc270d3c5c Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Thu, 24 Aug 2023 23:00:38 +0000 Subject: [PATCH 13/31] enhance: calculate deltas --- .github/workflows/generate-weekly-report.yml | 110 ++++++++++++++++--- 1 file changed, 92 insertions(+), 18 deletions(-) diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml index f08e9f44bbc5..0c489aff5cdf 100644 --- a/.github/workflows/generate-weekly-report.yml +++ b/.github/workflows/generate-weekly-report.yml @@ -46,7 +46,7 @@ jobs: const midnightYesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1); const sevenDaysAgo = new Date(midnightYesterday); sevenDaysAgo.setDate(midnightYesterday.getDate() - 7); - return { sevenDaysAgo, midnightYesterday}; + return { sevenDaysAgo, midnightYesterday }; } function filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }) { @@ -174,22 +174,32 @@ jobs: return stats } - function generateReport({issuesData}) { - const out = ['
      ']; + function generateReport({ issuesData, previousReport }) { + const out = [ + `## Format`, + "- `{CATEGORY}: {COUNT} ({CHANGE_FROM_PREVIOUS_WEEK})`", + "## Report", + '
        ']; for (const lbl of Object.keys(issuesData)) { - const section = []; - const {count, data, title} = issuesData[lbl]; - section.push(`
      • ${title}: ${count}`); - section.push(`
        + const section = [``]; + const { count, data, title } = issuesData[lbl]; + const previousCount = previousReport.issuesData[lbl].count; + section.push(`
      • ${title}: ${count} (${count - previousCount})`); + + // generate summary if issues exist + if (data.length !== 0) { + section.push(`
        Issues
          ${data.map((issue) => { - const {url, title, number} = issue; - return `
        • #${number} ${title}
        • `; - }).join('\n')} + const { url, title, number } = issue; + return `
        • #${number} ${title}
        • `; + }).join('\n')}
        `); + } + section.push('
      • '); out.push(section.join('\n')); } @@ -199,7 +209,7 @@ jobs: // add json data out.push('\n ## JSON Data'); out.push(''); - out.push( `
        + out.push(`
        Expand
                     {
        @@ -211,11 +221,11 @@ jobs:
                       return report;
                     }
                     
        -            async function createIssue({github, lookbackData, report}) {
        +            async function createIssue({ github, lookbackData, report, context }) {
                       const title = `Weekly Report: ${lookbackData.sevenDaysAgo.toISOString().slice(0, 10)} - ${lookbackData.midnightYesterday.toISOString().slice(0, 10)}`;
                       return github.rest.issues.create({
                         // TODO: change
        -                owner: "kevinslin",
        +                owner: context.repository_owner,
                         repo: "opentelemetry-collector-contrib",
                         title,
                         body: report,
        @@ -223,14 +233,78 @@ jobs:
                       })
                     }
                     
        +            async function getLastWeeksReport({ github, since, context }) {
        +              const issues = await github.rest.issues.listForRepo({
        +                owner: context.repository_owner,
        +                repo: 'opentelemetry-collector-contrib',
        +                state: 'all', // To get both open and closed issues
        +                labels: ["report"],
        +                since: since.toISOString(),
        +                per_page: 1,
        +                direction: "asc"
        +              });
        +              if (issues.data.length === 0) {
        +                throw new Error("no report found since " + since.toISOString());
        +              } 
        +              // grab earliest issue if multiple
        +              return issues.data[0];
        +            }
        +            
        +            function parseJsonFromText(text) {
        +              // Use regex to find the JSON data within the 
         tags
        +              const regex = /
        \s*([\s\S]*?)\s*<\/pre>/;
        +              const match = text.match(regex);
        +            
        +              if (match && match[1]) {
        +                // Parse the found string to JSON
        +                return JSON.parse(match[1]);
        +              } else {
        +                throw new Error("JSON data not found");
        +              }
        +            }
        +            
                     async function main({ github, context }) {
                       const lookbackData = genLookbackDates();
        -              const issuesData = await getIssuesData(github)
        -              const report = generateReport({issuesData})
        +              const issuesData = await getIssuesData(github);
        +            
        +              // BEGIN_DEBUG
        +              // writeJSONSync('./fixtures/lastweek-issues.json', issuesData);
        +              // issuesData = readJSONSync('./fixtures/lastweek-issues.json')
        +              // END_DEBUG
                     
        -              // const fs = require('fs');
        -              // const report = fs.readFileSync('./fixtures/report.md', 'utf8')
        -              await createIssue({github, lookbackData, report});
        +            
        +              const prevReportLookback = new Date(lookbackData.sevenDaysAgo)
        +              prevReportLookback.setDate(prevReportLookback.getDate() - 7)
        +              const previousReportIssue = await getLastWeeksReport({github, since: prevReportLookback, context});
        +              const {created_at, id, url, title} = previousReportIssue;
        +              debug({ msg: "previous issue", created_at, id, url, title })
        +            
        +              // BEGIN_DEBUG
        +              // previousReportIssue = JSON.parse(fs.readFileSync("./fixtures/issues.json", "utf8"))
        +              // END_DEBUG
        +            
        +              const previousReport = parseJsonFromText(previousReportIssue.body)
        +              // debug({ issuesData, previousReport })
        +            
        +              const report = generateReport({ issuesData, previousReport })
        +            
        +              // BEGIN_DEBUG
        +              // fs.writeFileSync('./fixtures/report.2.md', report);
        +              // END_DEBUG
        +              await createIssue({github, lookbackData, report, context});
        +            }
        +            
        +            function debug(msg) {
        +              console.log(JSON.stringify(msg, null, 2))
        +            }
        +            
        +            function readJSONSync(path) {
        +              return JSON.parse(fs.readFileSync(path, 'utf8'))
                     }
                     
        +            function writeJSONSync(path, data) {
        +              fs.writeFileSync(path, JSON.stringify(data, null, 2));
        +            }
        +            
        +            
                     await main({github, context})
        \ No newline at end of file
        
        From 8932abdf2c314448504783ad78b1fe40715425b2 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:23:20 +0000
        Subject: [PATCH 14/31] chore: update weekly report
        
        ---
         .github/workflows/generate-weekly-report.yml  | 295 +------------
         .../scripts/generate-weekly-report.js         | 412 ++++++++++++++++++
         2 files changed, 416 insertions(+), 291 deletions(-)
         create mode 100644 .github/workflows/scripts/generate-weekly-report.js
        
        diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml
        index 0c489aff5cdf..b3a13331629f 100644
        --- a/.github/workflows/generate-weekly-report.yml
        +++ b/.github/workflows/generate-weekly-report.yml
        @@ -12,299 +12,12 @@ jobs:
             runs-on: ubuntu-latest
             steps:
               - uses: actions/checkout@v3
        +      - run: npm install js-yaml
        +        working-directory: ./.github/workflows/scripts
               - uses: actions/github-script@v6
                 id: get-issues
                 with:
                   retries: 3
                   script: |
        -            async function getIssues(github, queryParams, filterPrs = true) {
        -              let allIssues = [];
        -              try {
        -                while (true) {
        -                  const response = await github.issues.listForRepo(queryParams);
        -                  // filter out pull requests
        -                  const issues = filterPrs ? response.data.filter(issue => !issue.pull_request) : response.data;
        -                  allIssues = allIssues.concat(issues);
        -            
        -                  // Check the 'link' header to see if there are more pages
        -                  const linkHeader = response.headers.link;
        -                  if (!linkHeader || !linkHeader.includes('rel="next"')) {
        -                    break;
        -                  }
        -            
        -                  queryParams.page++;
        -                }
        -                return allIssues;
        -              } catch (error) {
        -                console.error('Error fetching issues:', error);
        -                return [];
        -              }
        -            }
        -            
        -            function genLookbackDates() {
        -              const now = new Date();
        -              const midnightYesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
        -              const sevenDaysAgo = new Date(midnightYesterday);
        -              sevenDaysAgo.setDate(midnightYesterday.getDate() - 7);
        -              return { sevenDaysAgo, midnightYesterday };
        -            }
        -            
        -            function filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }) {
        -              const createdAt = new Date(issue.created_at);
        -              return createdAt >= sevenDaysAgo && createdAt <= midnightYesterday;
        -            }
        -            
        -            async function getNewIssues(github) {
        -              const { sevenDaysAgo, midnightYesterday } = genLookbackDates();
        -              const queryParams = {
        -                owner: 'open-telemetry',
        -                repo: 'opentelemetry-collector-contrib',
        -                state: 'all', // To get both open and closed issues
        -                per_page: 100, // Number of items per page (maximum allowed)
        -                page: 1, // Start with page 1
        -                since: sevenDaysAgo.toISOString(),
        -              };
        -            
        -              try {
        -                const allIssues = await getIssues(github, queryParams)
        -                const filteredIssues = allIssues.filter(issue => filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }));
        -                return filteredIssues;
        -              } catch (error) {
        -                console.error('Error fetching issues:', error);
        -                return [];
        -              }
        -            }
        -            
        -            async function getTargetLabelIssues(octokit, labels, filterPrs) {
        -              const queryParams = {
        -                owner: 'open-telemetry',
        -                repo: 'opentelemetry-collector-contrib',
        -                state: 'open',
        -                per_page: 100, // Number of items per page (maximum allowed)
        -                page: 1, // Start with page 1
        -                labels
        -              };
        -              try {
        -                const allIssues = await getIssues(octokit, queryParams, filterPrs)
        -                return allIssues;
        -              } catch (error) {
        -                console.error('Error fetching issues:', error);
        -                return [];
        -              }
        -            }
        -            
        -            async function getIssuesData(github) {
        -              const targetLabels = {
        -                "needs triage": {
        -                  filterPrs: true,
        -                  alias: "issuesTriage",
        -                },
        -                "ready to merge": {
        -                  filterPrs: false,
        -                  alias: "issuesReadyToMerge",
        -                },
        -                "Sponsor Needed": {
        -                  filterPrs: true,
        -                  alias: "issuesSponsorNeeded",
        -                },
        -              };
        -            
        -              const issuesNew = await getNewIssues(github.rest);
        -              const issuesWithLabels = {};
        -              for (const lbl of Object.keys(targetLabels)) {
        -                const filterPrs = targetLabels[lbl].filterPrs;
        -                const resp = await getTargetLabelIssues(github.rest, lbl, filterPrs);
        -                issuesWithLabels[lbl] = resp;
        -              }
        -            
        -              // tally results
        -              const stats = {
        -                issuesNew: {
        -                  title: "New issues",
        -                  count: 0,
        -                  data: []
        -                },
        -                issuesTriage: {
        -                  title: "Issues needing triage",
        -                  count: 0,
        -                  data: []
        -                },
        -                issuesReadyToMerge: {
        -                  title: "Issues ready to merge",
        -                  count: 0,
        -                  data: []
        -                },
        -                issuesSponsorNeeded: {
        -                  title: "Issues needing sponsorship",
        -                  count: 0,
        -                  data: []
        -                },
        -                issuesNewSponsorNeeded: {
        -                  title: "New issues needing sponsorship",
        -                  count: 0,
        -                  data: []
        -                },
        -              }
        -            
        -              // add new issues
        -              issuesNew.forEach(issue => {
        -                stats.issuesNew.count++;
        -                const { url, title, number } = issue;
        -                stats.issuesNew.data.push({ url, title, number });
        -              });
        -            
        -              // add issues with labels
        -              for (const lbl of Object.keys(targetLabels)) {
        -                const alias = targetLabels[lbl].alias;
        -                stats[alias].count = issuesWithLabels[lbl].length;
        -                stats[alias].data = issuesWithLabels[lbl].map(issue => {
        -                  const { url, title, number } = issue;
        -                  return { url, title, number };
        -                })
        -              }
        -            
        -              // add new issues with sponsor needed label
        -              const { sevenDaysAgo, midnightYesterday } = genLookbackDates();
        -              const sponsorNeededIssues = issuesWithLabels["Sponsor Needed"].filter(issue => filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }));
        -              sponsorNeededIssues.forEach(issue => {
        -                stats.issuesNewSponsorNeeded.count++;
        -                const { url, title, number } = issue;
        -                stats.issuesNewSponsorNeeded.data.push({ url, title, number });
        -              });
        -              return stats
        -            }
        -            
        -            function generateReport({ issuesData, previousReport }) {
        -              const out = [
        -                `## Format`,
        -                "- `{CATEGORY}: {COUNT} ({CHANGE_FROM_PREVIOUS_WEEK})`",
        -                "## Report",
        -                '
          ']; - - for (const lbl of Object.keys(issuesData)) { - const section = [``]; - const { count, data, title } = issuesData[lbl]; - const previousCount = previousReport.issuesData[lbl].count; - section.push(`
        • ${title}: ${count} (${count - previousCount})`); - - // generate summary if issues exist - if (data.length !== 0) { - section.push(`
          - Issues -
            - ${data.map((issue) => { - const { url, title, number } = issue; - return `
          • #${number} ${title}
          • `; - }).join('\n')} -
          -
          `); - } - - section.push('
        • '); - out.push(section.join('\n')); - } - - out.push('
        '); - - // add json data - out.push('\n ## JSON Data'); - out.push(''); - out.push(`
        - Expand -
        -            {
        -              "issuesData": ${JSON.stringify(issuesData, null, 2)}
        -            }
        -            
        -
        `); - const report = out.join('\n'); - return report; - } - - async function createIssue({ github, lookbackData, report, context }) { - const title = `Weekly Report: ${lookbackData.sevenDaysAgo.toISOString().slice(0, 10)} - ${lookbackData.midnightYesterday.toISOString().slice(0, 10)}`; - return github.rest.issues.create({ - // TODO: change - owner: context.repository_owner, - repo: "opentelemetry-collector-contrib", - title, - body: report, - labels: ["report"] - }) - } - - async function getLastWeeksReport({ github, since, context }) { - const issues = await github.rest.issues.listForRepo({ - owner: context.repository_owner, - repo: 'opentelemetry-collector-contrib', - state: 'all', // To get both open and closed issues - labels: ["report"], - since: since.toISOString(), - per_page: 1, - direction: "asc" - }); - if (issues.data.length === 0) { - throw new Error("no report found since " + since.toISOString()); - } - // grab earliest issue if multiple - return issues.data[0]; - } - - function parseJsonFromText(text) { - // Use regex to find the JSON data within the
         tags
        -              const regex = /
        \s*([\s\S]*?)\s*<\/pre>/;
        -              const match = text.match(regex);
        -            
        -              if (match && match[1]) {
        -                // Parse the found string to JSON
        -                return JSON.parse(match[1]);
        -              } else {
        -                throw new Error("JSON data not found");
        -              }
        -            }
        -            
        -            async function main({ github, context }) {
        -              const lookbackData = genLookbackDates();
        -              const issuesData = await getIssuesData(github);
        -            
        -              // BEGIN_DEBUG
        -              // writeJSONSync('./fixtures/lastweek-issues.json', issuesData);
        -              // issuesData = readJSONSync('./fixtures/lastweek-issues.json')
        -              // END_DEBUG
        -            
        -            
        -              const prevReportLookback = new Date(lookbackData.sevenDaysAgo)
        -              prevReportLookback.setDate(prevReportLookback.getDate() - 7)
        -              const previousReportIssue = await getLastWeeksReport({github, since: prevReportLookback, context});
        -              const {created_at, id, url, title} = previousReportIssue;
        -              debug({ msg: "previous issue", created_at, id, url, title })
        -            
        -              // BEGIN_DEBUG
        -              // previousReportIssue = JSON.parse(fs.readFileSync("./fixtures/issues.json", "utf8"))
        -              // END_DEBUG
        -            
        -              const previousReport = parseJsonFromText(previousReportIssue.body)
        -              // debug({ issuesData, previousReport })
        -            
        -              const report = generateReport({ issuesData, previousReport })
        -            
        -              // BEGIN_DEBUG
        -              // fs.writeFileSync('./fixtures/report.2.md', report);
        -              // END_DEBUG
        -              await createIssue({github, lookbackData, report, context});
        -            }
        -            
        -            function debug(msg) {
        -              console.log(JSON.stringify(msg, null, 2))
        -            }
        -            
        -            function readJSONSync(path) {
        -              return JSON.parse(fs.readFileSync(path, 'utf8'))
        -            }
        -            
        -            function writeJSONSync(path, data) {
        -              fs.writeFileSync(path, JSON.stringify(data, null, 2));
        -            }
        -            
        -            
        -            await main({github, context})
        \ No newline at end of file
        +            const script = require('.github/workflows/scripts/generate-weekly-report.js')
        +            console.log(script({github, context}))
        \ No newline at end of file
        diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js
        new file mode 100644
        index 000000000000..b3843bb72dae
        --- /dev/null
        +++ b/.github/workflows/scripts/generate-weekly-report.js
        @@ -0,0 +1,412 @@
        +const fs = require('fs');
        +const path = require('path');
        +const yaml = require('js-yaml');
        +
        +
        +function debug(msg) {
        +  console.log(JSON.stringify(msg, null, 2))
        +}
        +
        +async function getIssues(github, queryParams, filterPrs = true) {
        +  let allIssues = [];
        +  try {
        +    while (true) {
        +      const response = await github.issues.listForRepo(queryParams);
        +      // filter out pull requests
        +      const issues = filterPrs ? response.data.filter(issue => !issue.pull_request) : response.data;
        +      allIssues = allIssues.concat(issues);
        +
        +      // Check the 'link' header to see if there are more pages
        +      const linkHeader = response.headers.link;
        +      if (!linkHeader || !linkHeader.includes('rel="next"')) {
        +        break;
        +      }
        +
        +      queryParams.page++;
        +    }
        +    return allIssues;
        +  } catch (error) {
        +    console.error('Error fetching issues:', error);
        +    return [];
        +  }
        +}
        +
        +function genLookbackDates() {
        +  const now = new Date();
        +  const midnightYesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
        +  const sevenDaysAgo = new Date(midnightYesterday);
        +  sevenDaysAgo.setDate(midnightYesterday.getDate() - 7);
        +  return { sevenDaysAgo, midnightYesterday };
        +}
        +
        +function filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }) {
        +  const createdAt = new Date(issue.created_at);
        +  return createdAt >= sevenDaysAgo && createdAt <= midnightYesterday;
        +}
        +
        +async function getNewIssues(github) {
        +  const { sevenDaysAgo, midnightYesterday } = genLookbackDates();
        +  const queryParams = {
        +    owner: 'open-telemetry',
        +    repo: 'opentelemetry-collector-contrib',
        +    state: 'all', // To get both open and closed issues
        +    per_page: 100, // Number of items per page (maximum allowed)
        +    page: 1, // Start with page 1
        +    since: sevenDaysAgo.toISOString(),
        +  };
        +
        +  try {
        +    const allIssues = await getIssues(github, queryParams)
        +    const filteredIssues = allIssues.filter(issue => filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }));
        +    return filteredIssues;
        +  } catch (error) {
        +    console.error('Error fetching issues:', error);
        +    return [];
        +  }
        +}
        +
        +async function getTargetLabelIssues(octokit, labels, filterPrs) {
        +  const queryParams = {
        +    owner: 'open-telemetry',
        +    repo: 'opentelemetry-collector-contrib',
        +    state: 'open',
        +    per_page: 100, // Number of items per page (maximum allowed)
        +    page: 1, // Start with page 1
        +    labels
        +  };
        +  try {
        +    const allIssues = await getIssues(octokit, queryParams, filterPrs)
        +    return allIssues;
        +  } catch (error) {
        +    console.error('Error fetching issues:', error);
        +    return [];
        +  }
        +}
        +
        +async function getIssuesData(github) {
        +  const targetLabels = {
        +    "needs triage": {
        +      filterPrs: true,
        +      alias: "issuesTriage",
        +    },
        +    "ready to merge": {
        +      filterPrs: false,
        +      alias: "issuesReadyToMerge",
        +    },
        +    "Sponsor Needed": {
        +      filterPrs: true,
        +      alias: "issuesSponsorNeeded",
        +    },
        +  };
        +
        +  const issuesNew = await getNewIssues(github.rest);
        +  const issuesWithLabels = {};
        +  for (const lbl of Object.keys(targetLabels)) {
        +    const filterPrs = targetLabels[lbl].filterPrs;
        +    const resp = await getTargetLabelIssues(github.rest, lbl, filterPrs);
        +    issuesWithLabels[lbl] = resp;
        +  }
        +
        +  // tally results
        +  const stats = {
        +    issuesNew: {
        +      title: "New issues",
        +      count: 0,
        +      data: []
        +    },
        +    issuesTriage: {
        +      title: "Issues needing triage",
        +      count: 0,
        +      data: []
        +    },
        +    issuesReadyToMerge: {
        +      title: "Issues ready to merge",
        +      count: 0,
        +      data: []
        +    },
        +    issuesSponsorNeeded: {
        +      title: "Issues needing sponsorship",
        +      count: 0,
        +      data: []
        +    },
        +    issuesNewSponsorNeeded: {
        +      title: "New issues needing sponsorship",
        +      count: 0,
        +      data: []
        +    },
        +  }
        +
        +  // add new issues
        +  issuesNew.forEach(issue => {
        +    stats.issuesNew.count++;
        +    const { url, title, number } = issue;
        +    stats.issuesNew.data.push({ url, title, number });
        +  });
        +
        +  // add issues with labels
        +  for (const lbl of Object.keys(targetLabels)) {
        +    const alias = targetLabels[lbl].alias;
        +    stats[alias].count = issuesWithLabels[lbl].length;
        +    stats[alias].data = issuesWithLabels[lbl].map(issue => {
        +      const { url, title, number } = issue;
        +      return { url, title, number };
        +    })
        +  }
        +
        +  // add new issues with sponsor needed label
        +  const { sevenDaysAgo, midnightYesterday } = genLookbackDates();
        +  const sponsorNeededIssues = issuesWithLabels["Sponsor Needed"].filter(issue => filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }));
        +  sponsorNeededIssues.forEach(issue => {
        +    stats.issuesNewSponsorNeeded.count++;
        +    const { url, title, number } = issue;
        +    stats.issuesNewSponsorNeeded.data.push({ url, title, number });
        +  });
        +  return stats
        +}
        +
        +function generateReport({ issuesData, previousReport, componentData }) {
        +  const out = [
        +    `## Format`,
        +    "- `{CATEGORY}: {COUNT} ({CHANGE_FROM_PREVIOUS_WEEK})`",
        +    "## Issues Report",
        +    '
          ']; + + // generate report for issues + for (const lbl of Object.keys(issuesData)) { + const section = [``]; + const { count, data, title } = issuesData[lbl]; + + if (previousReport === null) { + section.push(`
        • ${title}: ${count}`); + } else { + const previousCount = previousReport.issuesData[lbl].count; + section.push(`
        • ${title}: ${count} (${count - previousCount})`); + } + + // generate summary if issues exist + if (data.length !== 0) { + section.push(`
          + Issues +
            + ${data.map((issue) => { + const { url, title, number } = issue; + return `
          • #${number} ${title}
          • `; + }).join('\n')} +
          +
          `); + } + + section.push('
        • '); + out.push(section.join('\n')); + } + out.push('
        '); + + // generate report for components + out.push('\n## Components Report', '
          '); + for (const lbl of Object.keys(componentData)) { + const section = [``]; + const data = componentData[lbl]; + const count = Object.keys(data).length; + + section.push(`
        • ${lbl}: ${count}`); + if (data.length !== 0) { + section.push(`
          + Components +
            + ${Object.keys(data).map((compName) => { + const {stability} = data[compName] + return `
          • ${compName}: ${JSON.stringify(stability)}}
          • `; + }).join('\n')} +
          +
          `); + } + section.push('
        • '); + out.push(section.join('\n')); + } + out.push('
        '); + + // add json data + out.push('\n ## JSON Data'); + out.push(''); + out.push(`
        +Expand +
        +{
        +  "issuesData": ${JSON.stringify(issuesData, null, 2)},
        +  "componentData": ${JSON.stringify(componentData, null, 2)}
        +}
        +
        +
        `); + const report = out.join('\n'); + return report; +} + +async function createIssue({ github, lookbackData, report, context }) { + const title = `Weekly Report: ${lookbackData.sevenDaysAgo.toISOString().slice(0, 10)} - ${lookbackData.midnightYesterday.toISOString().slice(0, 10)}`; + return github.rest.issues.create({ + owner: context.repository_owner, + repo: "opentelemetry-collector-contrib", + title, + body: report, + labels: ["report"] + }) +} + +async function getLastWeeksReport({ github, since, context }) { + const issues = await github.rest.issues.listForRepo({ + owner: context.repository_owner, + repo: 'opentelemetry-collector-contrib', + state: 'all', // To get both open and closed issues + labels: ["report"], + since: since.toISOString(), + per_page: 1, + direction: "asc" + }); + if (issues.data.length === 0) { + return null; + } + // grab earliest issue if multiple + return issues.data[0]; +} + +function parseJsonFromText(text) { + // Use regex to find the JSON data within the
         tags
        +  const regex = /
        \s*([\s\S]*?)\s*<\/pre>/;
        +  const match = text.match(regex);
        +
        +  if (match && match[1]) {
        +    // Parse the found string to JSON
        +    return JSON.parse(match[1]);
        +  } else {
        +    throw new Error("JSON data not found");
        +  }
        +}
        +
        +async function processIssues({ github, context, lookbackData }) {
        +  const issuesData = await getIssuesData(github);
        +
        +  const prevReportLookback = new Date(lookbackData.sevenDaysAgo)
        +  prevReportLookback.setDate(prevReportLookback.getDate() - 7)
        +  const previousReportIssue = await getLastWeeksReport({github, since: prevReportLookback, context});
        +  // initialize to zeros
        +  let previousReport = null;
        +
        +  if (previousReportIssue !== null) {
        +    const {created_at, id, url, title} = previousReportIssue;
        +    debug({ msg: "previous issue", created_at, id, url, title })
        +    previousReport = parseJsonFromText(previousReportIssue.body)
        +  }
        +
        +  return {issuesData, previousReport}
        +
        +
        +}
        +
        +const findFilesByName = (startPath, filter) => {
        +  let results = [];
        +
        +  // Check if directory exists
        +  let files;
        +  try {
        +      files = fs.readdirSync(startPath);
        +  } catch (error) {
        +      console.error("Error reading directory: ", startPath, error);
        +      return [];
        +  }
        +
        +  for (let i = 0; i < files.length; i++) {
        +      const filename = path.join(startPath, files[i]);
        +      let stat;
        +      try {
        +          stat = fs.lstatSync(filename);
        +      } catch (error) {
        +          console.error("Error stating file: ", filename, error);
        +          continue;
        +      }
        +      
        +      if (stat.isDirectory()) {
        +          const innerResults = findFilesByName(filename, filter); // Recursive call
        +          results = results.concat(innerResults);
        +      } else if (filename.indexOf(filter) >= 0) {
        +          results.push(filename);
        +      }
        +  }
        +  return results;
        +};
        +
        +function processFiles(files) {
        +  const results = {};
        +
        +  for (let filePath of files) {
        +      const component = path.basename(path.dirname(path.dirname(filePath)));  // Top level directory
        +      const name = path.basename(path.dirname(filePath));                      // Directory of the file
        +      const fileData = fs.readFileSync(filePath, 'utf8');                   // Read the file as a string
        +
        +      let data;
        +      try {
        +          data = yaml.load(fileData);  // Parse YAML
        +      } catch (err) {
        +          console.error(`Error parsing YAML for file ${filePath}:`, err);
        +          continue;  // Skip this file if there's an error in parsing
        +      }
        +
        +      if (!results[component]) {
        +          results[component] = {};
        +      }
        +
        +      results[component][name] = {
        +          path: filePath,
        +          data
        +      };
        +  }
        +
        +  return results;
        +}
        +
        +const processStatusResults = (results) => {
        +  const filteredResults = {};
        +
        +  for (const component in results) {
        +      for (const name in results[component]) {
        +          const { path, data } = results[component][name];
        +
        +          if (data && data.status && data.status.stability) {
        +              const { stability } = data.status;
        +              const statuses = ['unmaintained', 'deprecated'];
        +
        +              for (const status of statuses) {
        +                  if (stability[status] && stability[status].length > 0) {
        +                      if (!filteredResults[status]) {
        +                          filteredResults[status] = {};
        +                      }
        +                      filteredResults[status][name] = { path, stability: data.status.stability, component };
        +                  }
        +              }
        +          }
        +      }
        +  }
        +
        +  return filteredResults;
        +};
        +
        +async function processComponents() {
        +  const results = findFilesByName(`.`, 'metadata.yaml');
        +  const resultsClean = processFiles(results)
        +  const resultsWithStability = processStatusResults(resultsClean)
        +  return resultsWithStability
        +
        +}
        +
        +async function main({ github, context }) {
        +  const lookbackData = genLookbackDates();
        +  const {issuesData, previousReport} = await processIssues({ github, context, lookbackData })
        +  const componentData = await processComponents()
        +
        +  const report = generateReport({ issuesData, previousReport, componentData })
        +
        +  await createIssue({github, lookbackData, report, context});
        +}
        +
        +module.exports = async ({ github, context }) => {
        +  await main({ github, context })
        +}
        \ No newline at end of file
        
        From 61fd6132fdbb0bcd60bfeda1e6293e1f0c698852 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:27:36 +0000
        Subject: [PATCH 15/31] update repo owner
        
        ---
         .github/workflows/scripts/generate-weekly-report.js | 10 +++++-----
         1 file changed, 5 insertions(+), 5 deletions(-)
        
        diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js
        index b3843bb72dae..c344a7909f03 100644
        --- a/.github/workflows/scripts/generate-weekly-report.js
        +++ b/.github/workflows/scripts/generate-weekly-report.js
        @@ -44,10 +44,10 @@ function filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }) {
           return createdAt >= sevenDaysAgo && createdAt <= midnightYesterday;
         }
         
        -async function getNewIssues(github) {
        +async function getNewIssues({github, context}) {
           const { sevenDaysAgo, midnightYesterday } = genLookbackDates();
           const queryParams = {
        -    owner: 'open-telemetry',
        +    owner: context.repository_owner,
             repo: 'opentelemetry-collector-contrib',
             state: 'all', // To get both open and closed issues
             per_page: 100, // Number of items per page (maximum allowed)
        @@ -83,7 +83,7 @@ async function getTargetLabelIssues(octokit, labels, filterPrs) {
           }
         }
         
        -async function getIssuesData(github) {
        +async function getIssuesData({github, context}) {
           const targetLabels = {
             "needs triage": {
               filterPrs: true,
        @@ -99,7 +99,7 @@ async function getIssuesData(github) {
             },
           };
         
        -  const issuesNew = await getNewIssues(github.rest);
        +  const issuesNew = await getNewIssues({github: github.rest, context});
           const issuesWithLabels = {};
           for (const lbl of Object.keys(targetLabels)) {
             const filterPrs = targetLabels[lbl].filterPrs;
        @@ -283,7 +283,7 @@ function parseJsonFromText(text) {
         }
         
         async function processIssues({ github, context, lookbackData }) {
        -  const issuesData = await getIssuesData(github);
        +  const issuesData = await getIssuesData({github, context});
         
           const prevReportLookback = new Date(lookbackData.sevenDaysAgo)
           prevReportLookback.setDate(prevReportLookback.getDate() - 7)
        
        From a7a3e9d81d51d8bbc4740eed4fe70855b448b75c Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:32:43 +0000
        Subject: [PATCH 16/31] update context
        
        ---
         .github/workflows/scripts/generate-weekly-report.js | 8 ++++----
         1 file changed, 4 insertions(+), 4 deletions(-)
        
        diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js
        index c344a7909f03..41dc38fbea0e 100644
        --- a/.github/workflows/scripts/generate-weekly-report.js
        +++ b/.github/workflows/scripts/generate-weekly-report.js
        @@ -47,7 +47,7 @@ function filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }) {
         async function getNewIssues({github, context}) {
           const { sevenDaysAgo, midnightYesterday } = genLookbackDates();
           const queryParams = {
        -    owner: context.repository_owner,
        +    owner: 'open-telemetry',
             repo: 'opentelemetry-collector-contrib',
             state: 'all', // To get both open and closed issues
             per_page: 100, // Number of items per page (maximum allowed)
        @@ -65,9 +65,9 @@ async function getNewIssues({github, context}) {
           }
         }
         
        -async function getTargetLabelIssues(octokit, labels, filterPrs) {
        +async function getTargetLabelIssues({octokit, labels, filterPrs, context}) {
           const queryParams = {
        -    owner: 'open-telemetry',
        +    owner: context.repository_owner,
             repo: 'opentelemetry-collector-contrib',
             state: 'open',
             per_page: 100, // Number of items per page (maximum allowed)
        @@ -103,7 +103,7 @@ async function getIssuesData({github, context}) {
           const issuesWithLabels = {};
           for (const lbl of Object.keys(targetLabels)) {
             const filterPrs = targetLabels[lbl].filterPrs;
        -    const resp = await getTargetLabelIssues(github.rest, lbl, filterPrs);
        +    const resp = await getTargetLabelIssues({octokit: github.rest, labels: lbl, filterPrs, context});
             issuesWithLabels[lbl] = resp;
           }
         
        
        From fa4b556c8fab05c478b968b8eed7f377b7736c37 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:36:40 +0000
        Subject: [PATCH 17/31] add debug statement
        
        ---
         .github/workflows/scripts/generate-weekly-report.js | 1 +
         1 file changed, 1 insertion(+)
        
        diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js
        index 41dc38fbea0e..fbfb7bdb6808 100644
        --- a/.github/workflows/scripts/generate-weekly-report.js
        +++ b/.github/workflows/scripts/generate-weekly-report.js
        @@ -74,6 +74,7 @@ async function getTargetLabelIssues({octokit, labels, filterPrs, context}) {
             page: 1, // Start with page 1
             labels
           };
        +  debug({msg: "fetching issues", queryParams})
           try {
             const allIssues = await getIssues(octokit, queryParams, filterPrs)
             return allIssues;
        
        From 700fc62b4b93a05d024d828b4d620448abbf990f Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:38:57 +0000
        Subject: [PATCH 18/31] dump gh context
        
        ---
         .github/workflows/generate-weekly-report.yml | 4 ++++
         1 file changed, 4 insertions(+)
        
        diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml
        index b3a13331629f..d060203ed058 100644
        --- a/.github/workflows/generate-weekly-report.yml
        +++ b/.github/workflows/generate-weekly-report.yml
        @@ -14,6 +14,10 @@ jobs:
               - uses: actions/checkout@v3
               - run: npm install js-yaml
                 working-directory: ./.github/workflows/scripts
        +      - name: Dump GitHub context
        +        env:
        +          GITHUB_CONTEXT: ${{ toJson(github) }}
        +        run: echo "$GITHUB_CONTEXT"
               - uses: actions/github-script@v6
                 id: get-issues
                 with:
        
        From 94121746fe2511ea5825aed8443063ad736cf84f Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:46:39 +0000
        Subject: [PATCH 19/31] add context
        
        ---
         .github/workflows/scripts/generate-weekly-report.js | 1 +
         1 file changed, 1 insertion(+)
        
        diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js
        index fbfb7bdb6808..4728d332b208 100644
        --- a/.github/workflows/scripts/generate-weekly-report.js
        +++ b/.github/workflows/scripts/generate-weekly-report.js
        @@ -399,6 +399,7 @@ async function processComponents() {
         }
         
         async function main({ github, context }) {
        +  debug({msg: "running main", context})
           const lookbackData = genLookbackDates();
           const {issuesData, previousReport} = await processIssues({ github, context, lookbackData })
           const componentData = await processComponents()
        
        From 9c6b35b602a882ae6d382a28ab89cd2c062ca3ef Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:54:22 +0000
        Subject: [PATCH 20/31] update context
        
        ---
         .github/workflows/scripts/generate-weekly-report.js | 6 +++---
         1 file changed, 3 insertions(+), 3 deletions(-)
        
        diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js
        index 4728d332b208..af421611fbfd 100644
        --- a/.github/workflows/scripts/generate-weekly-report.js
        +++ b/.github/workflows/scripts/generate-weekly-report.js
        @@ -67,7 +67,7 @@ async function getNewIssues({github, context}) {
         
         async function getTargetLabelIssues({octokit, labels, filterPrs, context}) {
           const queryParams = {
        -    owner: context.repository_owner,
        +    owner: context.payload.repository.owner.login,
             repo: 'opentelemetry-collector-contrib',
             state: 'open',
             per_page: 100, // Number of items per page (maximum allowed)
        @@ -245,7 +245,7 @@ function generateReport({ issuesData, previousReport, componentData }) {
         async function createIssue({ github, lookbackData, report, context }) {
           const title = `Weekly Report: ${lookbackData.sevenDaysAgo.toISOString().slice(0, 10)} - ${lookbackData.midnightYesterday.toISOString().slice(0, 10)}`;
           return github.rest.issues.create({
        -    owner: context.repository_owner,
        +    owner: context.payload.repository.owner.login,
             repo: "opentelemetry-collector-contrib",
             title,
             body: report,
        @@ -255,7 +255,7 @@ async function createIssue({ github, lookbackData, report, context }) {
         
         async function getLastWeeksReport({ github, since, context }) {
           const issues = await github.rest.issues.listForRepo({
        -    owner: context.repository_owner,
        +    owner: context.payload.repository.owner.login,
             repo: 'opentelemetry-collector-contrib',
             state: 'all', // To get both open and closed issues
             labels: ["report"],
        
        From 31cc755a60ffe950285007e226f8e456512caa85 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:57:02 +0000
        Subject: [PATCH 21/31] add await
        
        ---
         .github/workflows/generate-weekly-report.yml | 2 +-
         1 file changed, 1 insertion(+), 1 deletion(-)
        
        diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml
        index d060203ed058..fd4d7b54c3ab 100644
        --- a/.github/workflows/generate-weekly-report.yml
        +++ b/.github/workflows/generate-weekly-report.yml
        @@ -24,4 +24,4 @@ jobs:
                   retries: 3
                   script: |
                     const script = require('.github/workflows/scripts/generate-weekly-report.js')
        -            console.log(script({github, context}))
        \ No newline at end of file
        +            await script({github, context})
        \ No newline at end of file
        
        From dc820f9abd5d4765848d912860f5a0bf5d0870ea Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 18:05:29 +0000
        Subject: [PATCH 22/31] get issues from the right place
        
        ---
         .../scripts/generate-weekly-report.js         | 21 ++++++++++++++-----
         1 file changed, 16 insertions(+), 5 deletions(-)
        
        diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js
        index af421611fbfd..bdecbe8560ea 100644
        --- a/.github/workflows/scripts/generate-weekly-report.js
        +++ b/.github/workflows/scripts/generate-weekly-report.js
        @@ -3,6 +3,9 @@ const path = require('path');
         const yaml = require('js-yaml');
         
         
        +const REPO_NAME = "opentelemetry-collector-contrib"
        +const REPO_OWNER = "open-telemetry"
        +
         function debug(msg) {
           console.log(JSON.stringify(msg, null, 2))
         }
        @@ -47,8 +50,8 @@ function filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }) {
         async function getNewIssues({github, context}) {
           const { sevenDaysAgo, midnightYesterday } = genLookbackDates();
           const queryParams = {
        -    owner: 'open-telemetry',
        -    repo: 'opentelemetry-collector-contrib',
        +    owner: REPO_OWNER,
        +    repo: REPO_NAME,
             state: 'all', // To get both open and closed issues
             per_page: 100, // Number of items per page (maximum allowed)
             page: 1, // Start with page 1
        @@ -65,10 +68,15 @@ async function getNewIssues({github, context}) {
           }
         }
         
        +/**
        + * 
        + * @param {*} param0 
        + * @returns 
        + */
         async function getTargetLabelIssues({octokit, labels, filterPrs, context}) {
           const queryParams = {
        -    owner: context.payload.repository.owner.login,
        -    repo: 'opentelemetry-collector-contrib',
        +    owner: REPO_OWNER,
        +    repo: REPO_NAME,
             state: 'open',
             per_page: 100, // Number of items per page (maximum allowed)
             page: 1, // Start with page 1
        @@ -84,6 +92,9 @@ async function getTargetLabelIssues({octokit, labels, filterPrs, context}) {
           }
         }
         
        +/**
        + * Get data required for issues report
        + */
         async function getIssuesData({github, context}) {
           const targetLabels = {
             "needs triage": {
        @@ -399,7 +410,7 @@ async function processComponents() {
         }
         
         async function main({ github, context }) {
        -  debug({msg: "running main", context})
        +  debug({msg: "running..."})
           const lookbackData = genLookbackDates();
           const {issuesData, previousReport} = await processIssues({ github, context, lookbackData })
           const componentData = await processComponents()
        
        From 3110b14bfc73d71a0f413daed5fef806c6fd4d70 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 18:48:45 +0000
        Subject: [PATCH 23/31] update date range
        
        ---
         .github/workflows/scripts/generate-weekly-report.js | 11 +++++++++--
         1 file changed, 9 insertions(+), 2 deletions(-)
        
        diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js
        index bdecbe8560ea..2eaf1dfd906e 100644
        --- a/.github/workflows/scripts/generate-weekly-report.js
        +++ b/.github/workflows/scripts/generate-weekly-report.js
        @@ -35,8 +35,15 @@ async function getIssues(github, queryParams, filterPrs = true) {
         }
         
         function genLookbackDates() {
        -  const now = new Date();
        -  const midnightYesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
        +  const now = new Date()
        +  const midnightYesterday = new Date(
        +    Date.UTC(
        +      now.getUTCFullYear(),
        +      now.getUTCMonth(),
        +      now.getUTCDate(),
        +      0, 0, 0, 0
        +    )
        +  );
           const sevenDaysAgo = new Date(midnightYesterday);
           sevenDaysAgo.setDate(midnightYesterday.getDate() - 7);
           return { sevenDaysAgo, midnightYesterday };
        
        From 3c78f74cd8b1469cf8b8592b8f30923b3d0fba64 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 18:55:01 +0000
        Subject: [PATCH 24/31] remove gh context
        
        ---
         .github/workflows/generate-weekly-report.yml | 4 ----
         1 file changed, 4 deletions(-)
        
        diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml
        index fd4d7b54c3ab..d9f0cdee0b97 100644
        --- a/.github/workflows/generate-weekly-report.yml
        +++ b/.github/workflows/generate-weekly-report.yml
        @@ -14,10 +14,6 @@ jobs:
               - uses: actions/checkout@v3
               - run: npm install js-yaml
                 working-directory: ./.github/workflows/scripts
        -      - name: Dump GitHub context
        -        env:
        -          GITHUB_CONTEXT: ${{ toJson(github) }}
        -        run: echo "$GITHUB_CONTEXT"
               - uses: actions/github-script@v6
                 id: get-issues
                 with:
        
        From bce9e7399ca93109e38562052706b62c1eea8194 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 18:59:07 +0000
        Subject: [PATCH 25/31] update cron
        
        ---
         .github/workflows/generate-weekly-report.yml | 5 +++--
         1 file changed, 3 insertions(+), 2 deletions(-)
        
        diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml
        index d9f0cdee0b97..d437a1377389 100644
        --- a/.github/workflows/generate-weekly-report.yml
        +++ b/.github/workflows/generate-weekly-report.yml
        @@ -4,8 +4,9 @@
         name: 'Generate Weekly Report'
         on:
           workflow_dispatch: 
        -  push:
        -    branches: [ chore/weekly-report-gen ]
        +  schedule:
        +    # run every tuesday at 1am UTC
        +    - cron: "0 1 * * 2"
         
         jobs:
           get_issues:
        
        From 0551502d7479a919709369652eb42d08990a00e7 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 16:54:37 -0700
        Subject: [PATCH 26/31] Update
         .github/workflows/scripts/generate-weekly-report.js
        
        Co-authored-by: Antoine Toulme 
        ---
         .github/workflows/scripts/generate-weekly-report.js | 3 +++
         1 file changed, 3 insertions(+)
        
        diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js
        index 2eaf1dfd906e..6317beda3c9d 100644
        --- a/.github/workflows/scripts/generate-weekly-report.js
        +++ b/.github/workflows/scripts/generate-weekly-report.js
        @@ -1,3 +1,6 @@
        +// Copyright The OpenTelemetry Authors
        +// SPDX-License-Identifier: Apache-2.0
        +
         const fs = require('fs');
         const path = require('path');
         const yaml = require('js-yaml');
        
        From f61c5f1460ec6d0f68814b058da4bc65a030ee50 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 16:54:45 -0700
        Subject: [PATCH 27/31] Update
         .github/workflows/scripts/generate-weekly-report.js
        
        Co-authored-by: Antoine Toulme 
        ---
         .github/workflows/scripts/generate-weekly-report.js | 5 -----
         1 file changed, 5 deletions(-)
        
        diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js
        index 6317beda3c9d..85211fe10613 100644
        --- a/.github/workflows/scripts/generate-weekly-report.js
        +++ b/.github/workflows/scripts/generate-weekly-report.js
        @@ -78,11 +78,6 @@ async function getNewIssues({github, context}) {
           }
         }
         
        -/**
        - * 
        - * @param {*} param0 
        - * @returns 
        - */
         async function getTargetLabelIssues({octokit, labels, filterPrs, context}) {
           const queryParams = {
             owner: REPO_OWNER,
        
        From ffc409588e93aa562b4dbd2f3b928dd7e1ca1a6e Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Sun, 3 Sep 2023 22:07:21 +0000
        Subject: [PATCH 28/31] enhance: support gh style checkboxes
        
        also switch out json links with html links
        ---
         .../scripts/generate-weekly-report.js         | 24 +++++++++----------
         1 file changed, 11 insertions(+), 13 deletions(-)
        
        diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js
        index 85211fe10613..4c7011a3a4a3 100644
        --- a/.github/workflows/scripts/generate-weekly-report.js
        +++ b/.github/workflows/scripts/generate-weekly-report.js
        @@ -156,7 +156,7 @@ async function getIssuesData({github, context}) {
           // add new issues
           issuesNew.forEach(issue => {
             stats.issuesNew.count++;
        -    const { url, title, number } = issue;
        +    const { html_url: url, title, number } = issue;
             stats.issuesNew.data.push({ url, title, number });
           });
         
        @@ -165,7 +165,7 @@ async function getIssuesData({github, context}) {
             const alias = targetLabels[lbl].alias;
             stats[alias].count = issuesWithLabels[lbl].length;
             stats[alias].data = issuesWithLabels[lbl].map(issue => {
        -      const { url, title, number } = issue;
        +      const { html_url: url, title, number } = issue;
               return { url, title, number };
             })
           }
        @@ -175,7 +175,7 @@ async function getIssuesData({github, context}) {
           const sponsorNeededIssues = issuesWithLabels["Sponsor Needed"].filter(issue => filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }));
           sponsorNeededIssues.forEach(issue => {
             stats.issuesNewSponsorNeeded.count++;
        -    const { url, title, number } = issue;
        +    const { html_url: url, title, number } = issue;
             stats.issuesNewSponsorNeeded.data.push({ url, title, number });
           });
           return stats
        @@ -201,15 +201,14 @@ function generateReport({ issuesData, previousReport, componentData }) {
             }
         
             // generate summary if issues exist
        +    // NOTE: the newline after  is required for markdown to render correctly
             if (data.length !== 0) {
               section.push(`
        - Issues -
          - ${data.map((issue) => { + Issues \n`); + section.push(`${data.map((issue) => { const { url, title, number } = issue; - return `
        • #${number} ${title}
        • `; + return `- [ ] ${title} ([#${number}](${url}))`; }).join('\n')} -
        `); } @@ -227,14 +226,13 @@ function generateReport({ issuesData, previousReport, componentData }) { section.push(`
      • ${lbl}: ${count}`); if (data.length !== 0) { + // NOTE: the newline after is required for markdown to render correctly section.push(`
        - Components -
          - ${Object.keys(data).map((compName) => { + Components \n`); + section.push(`${Object.keys(data).map((compName) => { const {stability} = data[compName] - return `
        • ${compName}: ${JSON.stringify(stability)}}
        • `; + return `- [ ] ${compName}: ${JSON.stringify(stability)}` }).join('\n')} -
        `); } section.push('
      • '); From 7a11c9ee7295178bd6b5bc5faffa10e9aa405e3f Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Tue, 12 Sep 2023 22:22:02 +0000 Subject: [PATCH 29/31] address pr issues --- .../scripts/generate-weekly-report.js | 51 +++++++++++-------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js index 4c7011a3a4a3..730e87eedf8f 100644 --- a/.github/workflows/scripts/generate-weekly-report.js +++ b/.github/workflows/scripts/generate-weekly-report.js @@ -13,11 +13,11 @@ function debug(msg) { console.log(JSON.stringify(msg, null, 2)) } -async function getIssues(github, queryParams, filterPrs = true) { +async function getIssues(octokit, queryParams, filterPrs = true) { let allIssues = []; try { while (true) { - const response = await github.issues.listForRepo(queryParams); + const response = await octokit.issues.listForRepo(queryParams); // filter out pull requests const issues = filterPrs ? response.data.filter(issue => !issue.pull_request) : response.data; allIssues = allIssues.concat(issues); @@ -57,7 +57,7 @@ function filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday }) { return createdAt >= sevenDaysAgo && createdAt <= midnightYesterday; } -async function getNewIssues({github, context}) { +async function getNewIssues({octokit, context}) { const { sevenDaysAgo, midnightYesterday } = genLookbackDates(); const queryParams = { owner: REPO_OWNER, @@ -69,7 +69,7 @@ async function getNewIssues({github, context}) { }; try { - const allIssues = await getIssues(github, queryParams) + const allIssues = await getIssues(octokit, queryParams) const filteredIssues = allIssues.filter(issue => filterOnDateRange({ issue, sevenDaysAgo, midnightYesterday })); return filteredIssues; } catch (error) { @@ -100,7 +100,7 @@ async function getTargetLabelIssues({octokit, labels, filterPrs, context}) { /** * Get data required for issues report */ -async function getIssuesData({github, context}) { +async function getIssuesData({octokit, context}) { const targetLabels = { "needs triage": { filterPrs: true, @@ -116,11 +116,11 @@ async function getIssuesData({github, context}) { }, }; - const issuesNew = await getNewIssues({github: github.rest, context}); + const issuesNew = await getNewIssues({octokit, context}); const issuesWithLabels = {}; for (const lbl of Object.keys(targetLabels)) { const filterPrs = targetLabels[lbl].filterPrs; - const resp = await getTargetLabelIssues({octokit: github.rest, labels: lbl, filterPrs, context}); + const resp = await getTargetLabelIssues({octokit, labels: lbl, filterPrs, context}); issuesWithLabels[lbl] = resp; } @@ -256,25 +256,29 @@ function generateReport({ issuesData, previousReport, componentData }) { return report; } -async function createIssue({ github, lookbackData, report, context }) { +async function createIssue({ octokit, lookbackData, report, context }) { const title = `Weekly Report: ${lookbackData.sevenDaysAgo.toISOString().slice(0, 10)} - ${lookbackData.midnightYesterday.toISOString().slice(0, 10)}`; - return github.rest.issues.create({ + return octokit.issues.create({ + // NOTE: we use the owner from the context because folks forking this repo might not have permission to (nor should they when developing) + // create issues in the upstream repository owner: context.payload.repository.owner.login, - repo: "opentelemetry-collector-contrib", + repo: REPO_NAME, title, body: report, labels: ["report"] }) } -async function getLastWeeksReport({ github, since, context }) { - const issues = await github.rest.issues.listForRepo({ +async function getLastWeeksReport({ octokit, since, context }) { + const issues = await octokit.issues.listForRepo({ + owner: context.payload.repository.owner.login, - repo: 'opentelemetry-collector-contrib', + repo: REPO_NAME, state: 'all', // To get both open and closed issues labels: ["report"], since: since.toISOString(), per_page: 1, + sort: "created", direction: "asc" }); if (issues.data.length === 0) { @@ -297,12 +301,12 @@ function parseJsonFromText(text) { } } -async function processIssues({ github, context, lookbackData }) { - const issuesData = await getIssuesData({github, context}); +async function processIssues({ octokit, context, lookbackData }) { + const issuesData = await getIssuesData({octokit, context}); const prevReportLookback = new Date(lookbackData.sevenDaysAgo) prevReportLookback.setDate(prevReportLookback.getDate() - 7) - const previousReportIssue = await getLastWeeksReport({github, since: prevReportLookback, context}); + const previousReportIssue = await getLastWeeksReport({octokit, since: prevReportLookback, context}); // initialize to zeros let previousReport = null; @@ -342,7 +346,7 @@ const findFilesByName = (startPath, filter) => { if (stat.isDirectory()) { const innerResults = findFilesByName(filename, filter); // Recursive call results = results.concat(innerResults); - } else if (filename.indexOf(filter) >= 0) { + } else if (path.basename(filename) == filter) { results.push(filename); } } @@ -353,7 +357,6 @@ function processFiles(files) { const results = {}; for (let filePath of files) { - const component = path.basename(path.dirname(path.dirname(filePath))); // Top level directory const name = path.basename(path.dirname(filePath)); // Directory of the file const fileData = fs.readFileSync(filePath, 'utf8'); // Read the file as a string @@ -365,6 +368,13 @@ function processFiles(files) { continue; // Skip this file if there's an error in parsing } + let component = path.basename(path.dirname(path.dirname(filePath))); + try { + // if component is defined in metadata status, prefer to use that + component = data.status.class; + } catch(err) { + } + if (!results[component]) { results[component] = {}; } @@ -414,13 +424,14 @@ async function processComponents() { async function main({ github, context }) { debug({msg: "running..."}) + const octokit = github.rest; const lookbackData = genLookbackDates(); - const {issuesData, previousReport} = await processIssues({ github, context, lookbackData }) + const {issuesData, previousReport} = await processIssues({ octokit, context, lookbackData }) const componentData = await processComponents() const report = generateReport({ issuesData, previousReport, componentData }) - await createIssue({github, lookbackData, report, context}); + await createIssue({octokit, lookbackData, report, context}); } module.exports = async ({ github, context }) => { From 80559bb590f76157ad2c1d7bd1051e7a1c4502a0 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Tue, 19 Sep 2023 14:14:19 -0700 Subject: [PATCH 30/31] Update .github/workflows/scripts/generate-weekly-report.js Co-authored-by: Tyler Helmuth <12352919+TylerHelmuth@users.noreply.github.com> --- .github/workflows/scripts/generate-weekly-report.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scripts/generate-weekly-report.js b/.github/workflows/scripts/generate-weekly-report.js index 730e87eedf8f..7b870a4b740c 100644 --- a/.github/workflows/scripts/generate-weekly-report.js +++ b/.github/workflows/scripts/generate-weekly-report.js @@ -436,4 +436,4 @@ async function main({ github, context }) { module.exports = async ({ github, context }) => { await main({ github, context }) -} \ No newline at end of file +} From f6a8605ac4769f62440c48f54ff7330bdd86fb57 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Tue, 19 Sep 2023 14:14:27 -0700 Subject: [PATCH 31/31] Update .github/workflows/generate-weekly-report.yml Co-authored-by: Tyler Helmuth <12352919+TylerHelmuth@users.noreply.github.com> --- .github/workflows/generate-weekly-report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/generate-weekly-report.yml b/.github/workflows/generate-weekly-report.yml index d437a1377389..5660fa6cf261 100644 --- a/.github/workflows/generate-weekly-report.yml +++ b/.github/workflows/generate-weekly-report.yml @@ -21,4 +21,4 @@ jobs: retries: 3 script: | const script = require('.github/workflows/scripts/generate-weekly-report.js') - await script({github, context}) \ No newline at end of file + await script({github, context})