Skip to content

feat: migrate to TypeScript, pnpm, and @octokit/rest#3

Open
GabrielHogan wants to merge 7 commits into
EndBug:mainfrom
GabrielHogan:main
Open

feat: migrate to TypeScript, pnpm, and @octokit/rest#3
GabrielHogan wants to merge 7 commits into
EndBug:mainfrom
GabrielHogan:main

Conversation

@GabrielHogan
Copy link
Copy Markdown

@GabrielHogan GabrielHogan commented May 20, 2026

The following PR and most of this code was written with the use of Generative AI. While I tested this extensively in the command line, AI models can produce incomplete, misleading, or erroneous information. I also did not test the JS tools beyond a basic implementation. I also did not test the enterprise functionality as I didn't have ready access to a self-hosted Github enterprise install. Github actions were also not tested.

My hope is that this was a good use of AI and the output is well-formed. It does pass all tests. Some further work is likely necessary, including bringing dependencies to their latest versions. I would love further input or guidance.

Thanks!
Gabe


Summary

This PR addresses #1 (Migrate to pnpm) and #2 (Migrate to TypeScript), and fixes a critical bug in alias label handling that manifests in EndBug/label-sync#302.

Closes #1
Closes #2
Closes EndBug/label-sync#302


Changes

TypeScript port (closes #2)

All source files have been rewritten in TypeScript:

  • lib/*.js + bin/github-label-sync.jssrc/*.ts
  • Full type definitions exported (GitHubLabel, ConfiguredLabel, SyncOptions, LabelDiff, etc.)
  • tsup produces dual ESM + CJS bundles (dist/esm/ and dist/cjs/)
  • src/index.cts shim provides proper module.exports = githubLabelSync CJS compatibility
  • package.json exports map for correct ESM/CJS resolution in all environments

pnpm migration (closes #1)

  • package-lock.json removed, pnpm-lock.yaml + pnpm-workspace.yaml added
  • All CI workflows updated to use pnpm/action-setup@v6

@octokit/rest migration

Replaced the deprecated octonode package with the official @octokit/rest v22:

  • All GitHub API calls now use typed Octokit methods
  • got and node.extend removed as direct dependencies (tsup bundles @octokit/rest and got)

Bug fix: getLabeledIssues silent empty array (related to EndBug/label-sync#302)

octokit.paginate silently returns an empty array when called with the endpoint method form (octokit.rest.issues.listForRepo). This caused alias labels to be deleted without re-labeling any issues that had them — the core failure mode reported in label-sync#302.

-  return this.octokit.paginate(this.octokit.rest.issues.listForRepo, {
-    owner, repo: repoName, labels: labelName, state: 'all', per_page: 100,
-  })
+  return this.octokit.paginate(
+    'GET /repos/{owner}/{repo}/issues',
+    { owner, repo: repoName, labels: labelName, state: 'all', per_page: 100 },
+  )

Using the route string form produces the correct paginated results.

Dependency updates

Package Before After
js-yaml ^3.14.1 ^4.1.1
commander ^6.2.1 ^12.1.0
octonode ^0.10.2 removed
node.extend ^2.0.2 removed
@octokit/rest ^22.0.1

Test modernization

  • Replaced mocha + sinon + istanbul with vitest + TypeScript
  • Tests rewritten in TypeScript with proper mocking via vi.mock
  • Coverage via @vitest/coverage-v8

Lint modernization

  • .eslintrc (ESLint v7) → eslint.config.js (ESLint v9 flat config + typescript-eslint)

CI workflow updates

  • actions/checkout v5/v4 → v6
  • actions/setup-node v4/v6 → v6 with Node.js 24.x
  • pnpm/action-setup@v6 added to all jobs
  • Release workflow now runs pnpm build before publish

README

  • Added ESM/TypeScript import example
  • Documented --endpoint CLI flag for GitHub Enterprise
  • Updated install/test commands for pnpm
  • Removed broken labels.json link (file no longer exists)

Test plan

  • pnpm install --frozen-lockfile
  • pnpm typecheck — passes with no errors
  • pnpm lint — passes
  • pnpm test:coverage — all tests pass with ≥90% coverage
  • pnpm build — produces dist/esm/ and dist/cjs/ artifacts
  • pnpm test:smoke — verifies CJS require, ESM import, and CLI --help all work correctly
  • Alias label merging correctly re-labels issues before deleting the old label

octokit.paginate silently returned an empty array when called with
the endpoint method form (octokit.rest.issues.listForRepo), causing
alias labels to be deleted without re-labeling issues that had them.
Switching to the route string form produces the correct results.
Replaces package-lock.json with pnpm-lock.yaml and updated CI workflows to be compatible with pnpm.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate to TypeScript Migrate to pnpm Actions fails when issues is disabled for the repository

1 participant