(opts: {
auth: DoltHubAuth;
upstream: { owner: string; db: string };
fork: { forkOwner: string; forkDb: string };
fetch?: typeof fetch;
hooks?: DoltFetchHooks;
})
| 189 | * no-op than to block a healthy mutation on a transient read error). |
| 190 | */ |
| 191 | export async function assertForkMainCurrent(opts: { |
| 192 | auth: DoltHubAuth; |
| 193 | upstream: { owner: string; db: string }; |
| 194 | fork: { forkOwner: string; forkDb: string }; |
| 195 | fetch?: typeof fetch; |
| 196 | hooks?: DoltFetchHooks; |
| 197 | }): Promise<void> { |
| 198 | const [upstreamHead, forkHead] = await Promise.all([ |
| 199 | readBranchHead({ |
| 200 | auth: opts.auth, |
| 201 | owner: opts.upstream.owner, |
| 202 | db: opts.upstream.db, |
| 203 | branch: 'main', |
| 204 | fetch: opts.fetch, |
| 205 | hooks: opts.hooks, |
| 206 | }), |
| 207 | readBranchHead({ |
| 208 | auth: opts.auth, |
| 209 | owner: opts.fork.forkOwner, |
| 210 | db: opts.fork.forkDb, |
| 211 | branch: 'main', |
| 212 | fetch: opts.fetch, |
| 213 | hooks: opts.hooks, |
| 214 | }), |
| 215 | ]); |
| 216 | |
| 217 | // If either read returned null, we can't decide. Don't block. |
| 218 | if (upstreamHead === null || forkHead === null) return; |
| 219 | if (upstreamHead === forkHead) return; |
| 220 | |
| 221 | // Drift detected. Compose the deep-link to the fork's pulls/new page, |
| 222 | // which is where DoltHub surfaces the "Sync from upstream" UI. |
| 223 | const syncUrl = `https://www.dolthub.com/repositories/${encodeURIComponent(opts.fork.forkOwner)}/${encodeURIComponent(opts.fork.forkDb)}/pulls/new`; |
| 224 | throw new WlError( |
| 225 | `Your DoltHub fork ${opts.fork.forkOwner}/${opts.fork.forkDb} is behind upstream ${opts.upstream.owner}/${opts.upstream.db}. ` + |
| 226 | `DoltHub's API doesn't support a programmatic fork-sync, so you'll need to sync manually before this mutation can proceed. ` + |
| 227 | `Visit ${syncUrl} and open a pull request from ${opts.upstream.owner}/${opts.upstream.db}:main into your fork's main, then merge it. ` + |
| 228 | `After the sync lands, retry this action.`, |
| 229 | 'precondition' |
| 230 | ); |
| 231 | } |
no test coverage detected