From f14762bd12c6f9c6bc663514d58447c43a27a927 Mon Sep 17 00:00:00 2001 From: "Fred K. Schott" Date: Tue, 31 Aug 2021 19:50:25 -0700 Subject: [PATCH] wip (#1284) --- .github/workflows/stat.yml | 31 +++++++++++ package.json | 1 + scripts/stats/index.js | 102 +++++++++++++++++++++++++++++++++++++ scripts/stats/stats.csv | 1 + yarn.lock | 51 ++++++++++++++++++- 5 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/stat.yml create mode 100644 scripts/stats/index.js create mode 100644 scripts/stats/stats.csv diff --git a/.github/workflows/stat.yml b/.github/workflows/stat.yml new file mode 100644 index 000000000..43b89be96 --- /dev/null +++ b/.github/workflows/stat.yml @@ -0,0 +1,31 @@ +name: 'Collect Stats' + +on: + schedule: + # * is a special character in YAML so you have to quote this string + - cron: '0 12 * * *' + +env: + node_version: 14 + +jobs: + stat: + runs-on: ubuntu-latest + steps: + # Check out code using git + - uses: actions/checkout@v2 + # Install Node 14 + - uses: actions/setup-node@v1 + with: + version: 14 + - run: npm install @octokit/action + # Node.js script can be anywhere. A good convention is to put local GitHub Actions + # into the `.github/actions` folder + - run: node scripts/stats/index.js + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Commit changes + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: '[ci] collect stats' + branch: ${{ github.head_ref }} diff --git a/package.json b/package.json index ddee752cd..91e6b63d7 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ }, "devDependencies": { "@changesets/cli": "^2.16.0", + "@octokit/action": "^3.15.1", "@snowpack/plugin-postcss": "^1.4.3", "@typescript-eslint/eslint-plugin": "^4.22.0", "@typescript-eslint/parser": "^4.18.0", diff --git a/scripts/stats/index.js b/scripts/stats/index.js new file mode 100644 index 000000000..7cea7bf4f --- /dev/null +++ b/scripts/stats/index.js @@ -0,0 +1,102 @@ +// @ts-check +import { Octokit } from '@octokit/action'; +import { execSync } from 'child_process'; +import { appendFileSync, readFileSync, writeFileSync } from 'fs'; + +const octokit = new Octokit(); +const owner = 'snowpackjs'; +const repo = 'astro'; + +// Relevant IDs captured via: https://docs.github.com/en/graphql/overview/explorer +// query { +// repository(name:"astro", owner:"snowpackjs") { +// project(number: 3) { +// columns(first: 100) { +// nodes { +// id +// databaseId +// name +// } +// } +// } +// } +// } + +const COLUMN_ID_BUGS_NEEDS_TRIAGE = 14724521; +const COLUMN_ID_BUGS_ACCEPTED = 14724515; +const COLUMN_ID_BUGS_PRIORITIZED = 14946516; +const COLUMN_ID_RFCS_NEEDS_DISCUSSION = 14946333; +const COLUMN_ID_RFCS_NEEDS_WORK = 14946353; +const COLUMN_ID_RFCS_ACCEPTED = 14946335; +const COLUMN_ID_RFCS_PRIORITIZED = 14946454; + +// CREATE LOCAL COPIES OF DATA (Useful for debugging locally) +// Command: +// GITHUB_ACTION=test GITHUB_TOKEN=XXXXXXXXX node scripts/stats/index.js +// Code: +// writeFileSync('pulls.json', JSON.stringify(await octokit.paginate("GET /repos/{owner}/{repo}/pulls", { +// owner, +// repo, +// }))); +// writeFileSync('issues.json', JSON.stringify(await octokit.paginate("GET /repos/{owner}/{repo}/issues", { +// owner, +// repo, +// }))); +// const issues = JSON.parse(readFileSync('issues.json').toString()); +// const pulls = JSON.parse(readFileSync('pulls.json').toString()); + +async function countCards(column_id) { + return octokit.paginate('GET /projects/columns/{column_id}/cards', { + column_id, + mediaType: { + previews: ['inertia'], + }, + }); +} +async function countCommits(since) { + return octokit.paginate('GET /repos/{owner}/{repo}/commits', { + owner, + repo, + since: since.toISOString(), + }) +} + +export async function run() { + const twentyFourHoursAgo = new Date(); + twentyFourHoursAgo.setDate(twentyFourHoursAgo.getDate() - 1); + + const pulls = await octokit.paginate('GET /repos/{owner}/{repo}/pulls', { + owner, + repo, + }); + const issues = await octokit.paginate('GET /repos/{owner}/{repo}/issues', { + owner, + repo, + }); + const entry = [ + // Date (Human Readable) + `"${new Date().toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}"`, + // Commits in last 24 hours + (await countCommits(twentyFourHoursAgo)).length, + // Pull requests + pulls.length, + // Open Issues + issues.length, + // Bugs: Needs Triage + (await countCards(COLUMN_ID_BUGS_NEEDS_TRIAGE)).length, + // Bugs: Accepted + (await countCards(COLUMN_ID_BUGS_ACCEPTED)).length + (await countCards(COLUMN_ID_BUGS_PRIORITIZED)).length, + // RFC: Needs Discussion + (await countCards(COLUMN_ID_RFCS_NEEDS_DISCUSSION)).length, + // RFC: Needs Work + (await countCards(COLUMN_ID_RFCS_NEEDS_WORK)).length, + // RFC: Accepted + (await countCards(COLUMN_ID_RFCS_ACCEPTED)).length + (await countCards(COLUMN_ID_RFCS_PRIORITIZED)).length, + // Date (ISO) + `"${new Date().toISOString()}"`, + ]; + + appendFileSync('scripts/stats/stats.csv', entry.join(',') + '\n'); +} + +run(); diff --git a/scripts/stats/stats.csv b/scripts/stats/stats.csv new file mode 100644 index 000000000..8d4d7d74f --- /dev/null +++ b/scripts/stats/stats.csv @@ -0,0 +1 @@ +Date,Commits (24hr),Open PRs,Open Issues,Bugs: Needs Triage,Bugs: Accepted,RFC: Needs Discussion,RFC: In Progress,RFC: Accepted,Date (ISO) diff --git a/yarn.lock b/yarn.lock index 613f649b3..591f97bf7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1510,14 +1510,34 @@ node-gyp "^7.1.0" read-package-json-fast "^2.0.1" -"@octokit/auth-token@^2.4.4": +"@octokit/action@^3.15.1": + version "3.15.1" + resolved "https://registry.yarnpkg.com/@octokit/action/-/action-3.15.1.tgz#c4e252f2be5d29d4fb01bcce534ea36ad6b85841" + integrity sha512-JZizqoCJ5REHonNWUNtWE3EducK7e8TXOuuKceRqKX0eKjLMmf2M0ZS7gKCcJ5zntw5Fl08to9dHX5GBXvyKBA== + dependencies: + "@octokit/auth-action" "^1.2.0" + "@octokit/core" "^3.0.0" + "@octokit/plugin-paginate-rest" "^2.2.4" + "@octokit/plugin-rest-endpoint-methods" "5.9.0" + "@octokit/types" "^6.16.1" + https-proxy-agent "^5.0.0" + +"@octokit/auth-action@^1.2.0": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@octokit/auth-action/-/auth-action-1.3.3.tgz#20004fbf0b4a7012f4f7fc2c54d263749239cd5f" + integrity sha512-8v4c/pw6HTxsF7pCgJoox/q4KKov4zkgLxEGGqLOZPSZaHf1LqdLlj5m5x5c1bKNn38uQXNvJKEnKX1qJlGeQQ== + dependencies: + "@octokit/auth-token" "^2.4.0" + "@octokit/types" "^6.0.3" + +"@octokit/auth-token@^2.4.0", "@octokit/auth-token@^2.4.4": version "2.4.5" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.5.tgz#568ccfb8cb46f36441fac094ce34f7a875b197f3" integrity sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA== dependencies: "@octokit/types" "^6.0.3" -"@octokit/core@^3.5.0": +"@octokit/core@^3.0.0", "@octokit/core@^3.5.0": version "3.5.1" resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.5.1.tgz#8601ceeb1ec0e1b1b8217b960a413ed8e947809b" integrity sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw== @@ -1548,6 +1568,11 @@ "@octokit/types" "^6.0.3" universal-user-agent "^6.0.0" +"@octokit/openapi-types@^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-10.0.0.tgz#db4335de99509021f501fc4e026e6ff495fe1e62" + integrity sha512-k1iO2zKuEjjRS1EJb4FwSLk+iF6EGp+ZV0OMRViQoWhQ1fZTk9hg1xccZII5uyYoiqcbC73MRBmT45y1vp2PPg== + "@octokit/openapi-types@^9.5.0": version "9.7.0" resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-9.7.0.tgz#9897cdefd629cd88af67b8dbe2e5fb19c63426b2" @@ -1558,6 +1583,13 @@ resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437" integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw== +"@octokit/plugin-paginate-rest@^2.2.4": + version "2.16.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.0.tgz#09dbda2e5fbca022e3cdf76b63618f7b357c9f0c" + integrity sha512-8YYzALPMvEZ35kgy5pdYvQ22Roz+BIuEaedO575GwE2vb/ACDqQn0xQrTJR4tnZCJn7pi8+AWPVjrFDaERIyXQ== + dependencies: + "@octokit/types" "^6.26.0" + "@octokit/plugin-paginate-rest@^2.6.2": version "2.15.1" resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.15.1.tgz#264189dd3ce881c6c33758824aac05a4002e056a" @@ -1578,6 +1610,14 @@ "@octokit/types" "^6.25.0" deprecation "^2.3.1" +"@octokit/plugin-rest-endpoint-methods@5.9.0": + version "5.9.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.9.0.tgz#f9a7d8411e7e4e49a65fc95b5cc23cf96bf05e1f" + integrity sha512-Rz67pg+rEJq2Qn/qfHsMiBoP7GL5NDn8Gg0ezGznZ745Ixn1gPusZYZqCXNhICYrIZaVXmusNP0iwPdphJneqQ== + dependencies: + "@octokit/types" "^6.26.0" + deprecation "^2.3.1" + "@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.1.0.tgz#9e150357831bfc788d13a4fd4b1913d60c74d677" @@ -1616,6 +1656,13 @@ dependencies: "@octokit/openapi-types" "^9.5.0" +"@octokit/types@^6.26.0": + version "6.26.0" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.26.0.tgz#b8af298485d064ad9424cb41520541c1bf820346" + integrity sha512-RDxZBAFMtqs1ZPnbUu1e7ohPNfoNhTiep4fErY7tZs995BeHu369Vsh5woMIaFbllRWEZBfvTCS4hvDnMPiHrA== + dependencies: + "@octokit/openapi-types" "^10.0.0" + "@rollup/plugin-commonjs@^16.0.0": version "16.0.0" resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-16.0.0.tgz#169004d56cd0f0a1d0f35915d31a036b0efe281f"