@10stars/config 17.0.0 → 17.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/link-remote.ts +30 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@10stars/config",
3
- "version": "17.0.0",
3
+ "version": "17.0.1",
4
4
  "private": false,
5
5
  "bin": {
6
6
  "config": "./src/index.ts"
@@ -125,10 +125,13 @@ const bfsSiblings = async (cwd: string, visit: (sib: string) => Promise<void>):
125
125
  }
126
126
  }
127
127
 
128
- const branchExists = (url: string, ref: string): boolean =>
129
- Boolean(tryGit([`ls-remote`, `--heads`, url, ref]))
130
-
131
- /** Branch-first: current PR branch, then push branch, then `develop`, then `production`. */
128
+ /**
129
+ * Branch-first: current PR branch, then push branch, then `develop`, then `production`. A single
130
+ * `ls-remote --heads` lists every head in one network round-trip; candidates are matched locally
131
+ * (avoids one request per ref). A non-zero exit means the repo is unreadable (private + missing/
132
+ * unauthorized clone token → "Repository not found") — surfaced immediately rather than masquerading
133
+ * as "No branch found".
134
+ */
132
135
  const resolveRef = (url: string, repo: string): string => {
133
136
  const candidates = [
134
137
  process.env.GITHUB_HEAD_REF, // pull_request events
@@ -137,8 +140,29 @@ const resolveRef = (url: string, repo: string): string => {
137
140
  `production`,
138
141
  ].filter((v): v is string => Boolean(v))
139
142
 
140
- for (const ref of candidates) if (branchExists(url, ref)) return ref
141
- throw new Error(`No branch found for ${repo}; tried: ${candidates.join(`, `)}`)
143
+ let heads: string
144
+ try {
145
+ heads = git([`ls-remote`, `--heads`, url])
146
+ } catch (err) {
147
+ const stderr = (err as { stderr?: string | Buffer })?.stderr
148
+ throw new Error(
149
+ `Cannot read ${url}: repo is unreachable — if private, the clone token is missing or ` +
150
+ `unauthorized. Pass app-key to setup-siblings and install the GitHub App on this repo ` +
151
+ `with contents:read.\n${(stderr ?? (err as Error)?.message ?? ``).toString().trim()}`,
152
+ )
153
+ }
154
+
155
+ // Each line is "<sha>\trefs/heads/<branch>"; a branch may itself contain slashes (e.g. alice/x).
156
+ const present = new Set(
157
+ heads
158
+ .split(`\n`)
159
+ .map((line) => line.split(`refs/heads/`)[1])
160
+ .filter(Boolean),
161
+ )
162
+ for (const ref of candidates) if (present.has(ref)) return ref
163
+ throw new Error(
164
+ `No branch found for ${repo}; tried: ${candidates.join(`, `)} (repo reachable, refs absent)`,
165
+ )
142
166
  }
143
167
 
144
168
  const headSha = (dir: string): string | null => tryGit([`rev-parse`, `HEAD`], dir)