Commit 2ba83a8

Anton Golub <antongolub@antongolub.com>
2023-10-10 22:07:20
feat: provide `dryrun` mode
1 parent ee5d4a5
src/main.ts
@@ -14,7 +14,7 @@ import { updateBadges } from './update-badges.js'
 void (async function main() {
   const { env } = process
   const argv = minimist(process.argv.slice(2), {
-    string: ['data', 'repo', 'token', 'size', 'user'],
+    string: ['data', 'repo', 'token', 'size', 'user', 'dryrun'],
   })
   const {
     token = env.GITHUB_TOKEN,
@@ -22,6 +22,7 @@ void (async function main() {
     user: username = argv._[0] || env.GITHUB_USER,
     data: dataPath = '',
     size,
+    dryrun,
   } = argv
   const [owner, repo] = repository?.split('/', 2) || []
 
@@ -100,7 +101,7 @@ void (async function main() {
   console.log('Badges', badges)
 
   if (owner && repo) {
-    await updateBadges(octokit, owner, repo, badges, oldJson, jsonSha)
-    await updateReadme(octokit, owner, repo, badges, size)
+    await updateBadges(octokit, owner, repo, badges, oldJson, jsonSha, dryrun)
+    await updateReadme(octokit, owner, repo, badges, size, dryrun)
   }
 })()
src/update-badges.ts
@@ -1,6 +1,6 @@
 import { Octokit, RequestError } from 'octokit'
 import { Badge } from './badges.js'
-import { quoteAttr } from './utils.js'
+import { quoteAttr, upload } from './utils.js'
 
 export async function updateBadges(
   octokit: Octokit,
@@ -9,6 +9,7 @@ export async function updateBadges(
   badges: Badge[],
   oldJson: string | undefined,
   jsonSha: string | undefined,
+  dryrun: string | undefined,
 ) {
   const myBadgesPath = 'my-badges/my-badges.json'
 
@@ -16,19 +17,23 @@ export async function updateBadges(
   if (newJson == oldJson) {
     console.log('No change in my-badges.json')
   } else {
-    console.log('Updating my-badges.json')
-    await octokit.request('PUT /repos/{owner}/{repo}/contents/{path}', {
-      owner,
-      repo,
-      path: myBadgesPath,
-      message: 'Update my-badges',
-      committer: {
-        name: 'My Badges',
-        email: 'my-badges@github.com',
+    await upload(
+      octokit,
+      'PUT /repos/{owner}/{repo}/contents/{path}',
+      {
+        owner,
+        repo,
+        path: myBadgesPath,
+        message: 'Update my-badges',
+        committer: {
+          name: 'My Badges',
+          email: 'my-badges@github.com',
+        },
+        content: Buffer.from(newJson, 'utf8').toString('base64'),
+        sha: jsonSha,
       },
-      content: Buffer.from(newJson, 'utf8').toString('base64'),
-      sha: jsonSha,
-    })
+      dryrun,
+    )
   }
 
   for (const badge of badges) {
@@ -65,18 +70,22 @@ export async function updateBadges(
       continue
     }
 
-    console.log(`Uploading ${badgePath}`)
-    await octokit.request('PUT /repos/{owner}/{repo}/contents/{path}', {
-      owner,
-      repo,
-      path: badgePath,
-      message: sha ? `Update ${badge.id}.md` : `Add ${badge.id}.md`,
-      committer: {
-        name: 'My Badges',
-        email: 'my-badges@github.com',
+    await upload(
+      octokit,
+      'PUT /repos/{owner}/{repo}/contents/{path}',
+      {
+        owner,
+        repo,
+        path: badgePath,
+        message: sha ? `Update ${badge.id}.md` : `Add ${badge.id}.md`,
+        committer: {
+          name: 'My Badges',
+          email: 'my-badges@github.com',
+        },
+        content: Buffer.from(content, 'utf8').toString('base64'),
+        sha: sha,
       },
-      content: Buffer.from(content, 'utf8').toString('base64'),
-      sha: sha,
-    })
+      dryrun,
+    )
   }
 }
src/update-readme.ts
@@ -1,6 +1,6 @@
 import { Octokit } from 'octokit'
 import { Badge } from './badges.js'
-import { quoteAttr } from './utils.js'
+import { quoteAttr, upload } from './utils.js'
 
 export async function updateReadme(
   octokit: Octokit,
@@ -8,6 +8,7 @@ export async function updateReadme(
   repo: string,
   badges: Badge[],
   size: number | string = 64,
+  dryrun: string | undefined,
 ) {
   console.log('Loading README.md')
   const readme = await octokit.request<'readme'>(
@@ -48,17 +49,21 @@ export async function updateReadme(
       content.slice(start)
   }
 
-  console.log('Updating README.md')
-  await octokit.request('PUT /repos/{owner}/{repo}/contents/{path}', {
-    owner,
-    repo,
-    path: readme.data.path,
-    message: 'Update my-badges',
-    committer: {
-      name: 'My Badges',
-      email: 'my-badges@github.com',
+  await upload(
+    octokit,
+    'PUT /repos/{owner}/{repo}/contents/{path}',
+    {
+      owner,
+      repo,
+      path: readme.data.path,
+      message: 'Update my-badges',
+      committer: {
+        name: 'My Badges',
+        email: 'my-badges@github.com',
+      },
+      content: Buffer.from(content, 'utf8').toString('base64'),
+      sha: readme.data.sha,
     },
-    content: Buffer.from(content, 'utf8').toString('base64'),
-    sha: readme.data.sha,
-  })
+    dryrun,
+  )
 }
src/utils.ts
@@ -1,3 +1,5 @@
+import fs from 'node:fs/promises'
+import { Octokit } from 'octokit'
 import { Commit, Pull } from './collect/collect.js'
 
 export function linkCommit(commit: Commit): string {
@@ -22,3 +24,18 @@ export function quoteAttr(s: string) {
 }
 
 export const expectType = <T>(expression: T) => void 0
+
+export const upload = async (
+  octokit: Octokit,
+  route: Parameters<Octokit['request']>[0],
+  data: Parameters<Octokit['request']>[1],
+  dryrun?: string,
+) => {
+  if (dryrun) {
+    console.log(`Skipped pushing ${data?.path} (dryrun)`)
+    return fs.writeFile(data?.path as string, data?.content as string)
+  }
+
+  console.log(`Uploading ${data?.path}`)
+  return octokit.request(route, data)
+}
README.md
@@ -90,13 +90,14 @@ jobs:
 - Start **my-badges** workflow, or wait for it to run automatically.
 
 ## Configuration
-| Param   | ENV alias      | Description                                                                                | Default |
-|---------|----------------|--------------------------------------------------------------------------------------------|---------|
-| `token` | `GITHUB_TOKEN` | Auth token                                                                                 |         |
-| `user`  | `GITHUB_USER`  | Username                                                                                   |         |
-| `repo`  | `GITHUB_REPO`  | Repository name                                                                            |         |
-| `data`  |                | Path to JSON to generate badges. If empty, required data will be obtained from the GH API  |         |
-| `size`  |                | Badge size for README.md, px                                                               | 64      |
+| Param    | ENV alias      | Description                                                                               | Default |
+|----------|----------------|-------------------------------------------------------------------------------------------|---------|
+| `token`  | `GITHUB_TOKEN` | Auth token                                                                                |         |
+| `user`   | `GITHUB_USER`  | Username                                                                                  |         |
+| `repo`   | `GITHUB_REPO`  | Repository name                                                                           |         |
+| `data`   |                | Path to JSON to generate badges. If empty, required data will be obtained from the GH API |         |
+| `size`   |                | Badge size for README.md, px                                                              | 64      |
+| `dryrun` |                | Generate badges, but skip pushing to git                                                  |         |
 
 ## Contributing badges