From c64c4b0ae3a0763078cd00384ada45e58993ee62 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 18:04:41 +0000 Subject: [PATCH 01/28] 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 06def3f0890164bcc2c9ca6fbbc067a482d94997 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 18:09:06 +0000 Subject: [PATCH 02/28] 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 b429419fa6eb..5a05bc62d939 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 f4e852345764..6bc56957a9b2 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 e8b5cacd6e2c..010cf2f2b2e3 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 5615bcec957b..17cfdc41e48a 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 255a0bbc5194..f6110380d343 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 dcf6b293d3f7..3759b9763869 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 57c49a3441bc..114151a1f1c1 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 432d1e17a8ef0144f296f290b64c970a85de575a Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 18:12:40 +0000 Subject: [PATCH 03/28] 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 3988a876ded1c5bbae30d180b1ee29c285ca4c06 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 18:16:12 +0000 Subject: [PATCH 04/28] 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 687f84d3eb32695d44287db7a78f13a263dee808 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 18:45:22 +0000 Subject: [PATCH 05/28] 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 86808b1ad80fc54e4aa1426bb9fcd9bd9bd78f28 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 19:40:45 +0000 Subject: [PATCH 06/28] 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 c9419e5349d69977ea0b85103c5a49f705758b3d Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 19:42:19 +0000 Subject: [PATCH 07/28] 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 cb93fda9ca73..5db249dffea7 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 268369d1186bd5c06969bcb678860a1e67779739 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 19:48:18 +0000 Subject: [PATCH 08/28] 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 a3342e328ea07ba6101c4c2133aaad5814c5a5d9 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 20:13:29 +0000 Subject: [PATCH 09/28] 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 2e61f2fc46e69e3ffd9d59355e9565ed14c18ed3 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 21:40:20 +0000 Subject: [PATCH 10/28] 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 5a05bc62d939..b429419fa6eb 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 6bc56957a9b2..f4e852345764 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 010cf2f2b2e3..e8b5cacd6e2c 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 17cfdc41e48a..5615bcec957b 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 f6110380d343..255a0bbc5194 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 3759b9763869..dcf6b293d3f7 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 114151a1f1c1..57c49a3441bc 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 ae047762e4b8836e4d7c8e9965bdc7c7d6ab2a69 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 21:40:28 +0000 Subject: [PATCH 11/28] 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 5db249dffea7..cb93fda9ca73 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 dd88dae40f67ec6e0dfc0f290dc0e0397c4201a7 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 20 Aug 2023 21:45:23 +0000 Subject: [PATCH 12/28] 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 9df55be86484c1af39cf54358be313a1538f7420 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Thu, 24 Aug 2023 23:00:38 +0000 Subject: [PATCH 13/28] 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 3b82356a8d4ffcc72333b38ee2703c64b6dfeba7 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:23:20 +0000
        Subject: [PATCH 14/28] 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 d1dc15653d3141b208cb8af72fc8f67cdf7f6535 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:27:36 +0000
        Subject: [PATCH 15/28] 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 2dfae94563d07d5cf3823e95ab3e81681d4283e5 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:32:43 +0000
        Subject: [PATCH 16/28] 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 288811500f1d44406e1c9ee2b6d99f4b8ae67fa7 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:36:40 +0000
        Subject: [PATCH 17/28] 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 d82550cf8c384b4d0575ab48948e463df0bf645e Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:38:57 +0000
        Subject: [PATCH 18/28] 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 648573d522980ab8c6adec9a734514b7dbb4eef5 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:46:39 +0000
        Subject: [PATCH 19/28] 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 ce6aab611cd757fc3ec5bb5600cf0f1f8467c46c Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:54:22 +0000
        Subject: [PATCH 20/28] 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 24582d8901fa83902acce69a2d027dd5c25f25b0 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 17:57:02 +0000
        Subject: [PATCH 21/28] 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 8913727e3339290899a41e557173e786a220839a Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 18:05:29 +0000
        Subject: [PATCH 22/28] 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 1192d9c71e41fa13ff5da51c3e53b0c2a1b90229 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 18:48:45 +0000
        Subject: [PATCH 23/28] 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 0da39de8b5d8e63a677f1af490d2690896593f80 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 18:55:01 +0000
        Subject: [PATCH 24/28] 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 a01a1455f51de14e3461f7ca5333a35739c37a0b Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 18:59:07 +0000
        Subject: [PATCH 25/28] 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 3391e8b528f933bb63125d5c47b836e9041854c0 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 16:54:37 -0700
        Subject: [PATCH 26/28] 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 68a25b24bc823346adc011695dcd2012806b9033 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Fri, 25 Aug 2023 16:54:45 -0700
        Subject: [PATCH 27/28] 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 1e830957d6311b0e611da7c269c07dacf495e416 Mon Sep 17 00:00:00 2001
        From: Kevin Lin 
        Date: Sun, 3 Sep 2023 22:07:21 +0000
        Subject: [PATCH 28/28] 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('
      • ');