Add the experimental forge capability seam: - dsh-experimental-forge: provider-neutral repository and change request references, a provider registry, and shared status polling. Watchers of one change request share one loop; each forge has one batched fetch in flight, and the cadence follows check, mergeability, and lifecycle state. - dsh-experimental-forge-github: GitHub provider that runs the GitHub CLI on the host with a scrubbed environment and reads every due pull request of a host in one GraphQL query. - dsh-experimental-forge-session: a host-only projection derives Session bindings from gh pr create and git push shell results and from plugin:forge-session/binding records; push results trigger head-branch discovery of open pull requests, and Session watchers poll bound change requests through ctx.forge.
61 lines
2.3 KiB
TypeScript
61 lines
2.3 KiB
TypeScript
import { Context } from '@deepseek-ai/cordis'
|
|
import ForgeService from '@deepseek-ai/dsh-experimental-forge'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import * as ForgeGitHub from '../src/index.ts'
|
|
|
|
let ctx: Context | undefined
|
|
|
|
afterEach(async () => {
|
|
await ctx?.fiber.dispose()
|
|
ctx = undefined
|
|
})
|
|
|
|
async function forge(): Promise<Context> {
|
|
ctx = new Context()
|
|
await ctx.plugin(ForgeService)
|
|
return ctx
|
|
}
|
|
|
|
describe('forge-github plugin', () => {
|
|
it('registers the GitHub provider for the configured hosts', async () => {
|
|
const context = await forge()
|
|
await context.plugin(ForgeGitHub, { hosts: ['github.com', 'ghe.corp.example'] })
|
|
|
|
expect(context.forge.changeRequestFromUrl('https://github.com/octo/demo/pull/1')).toEqual({
|
|
repository: { forge: 'github', host: 'github.com', owner: 'octo', name: 'demo' },
|
|
number: 1,
|
|
})
|
|
expect(context.forge.repositoryFromRemote('[email protected]:team/svc.git')).toEqual({ forge: 'github', host: 'ghe.corp.example', owner: 'team', name: 'svc' })
|
|
})
|
|
|
|
it('serves github.com by default', async () => {
|
|
const context = await forge()
|
|
await context.plugin(ForgeGitHub, {})
|
|
|
|
expect(context.forge.repositoryFromRemote('https://github.com/octo/demo.git')).toBeDefined()
|
|
expect(context.forge.repositoryFromRemote('https://ghe.corp.example/team/svc.git')).toBeUndefined()
|
|
})
|
|
|
|
it('unregisters the provider when its fiber is disposed', async () => {
|
|
const context = await forge()
|
|
const fiber = context.plugin(ForgeGitHub, {})
|
|
await fiber
|
|
|
|
await fiber.dispose()
|
|
|
|
expect(context.forge.changeRequestFromUrl('https://github.com/octo/demo/pull/1')).toBeUndefined()
|
|
})
|
|
|
|
it.each([
|
|
[{ ghCommand: ' ' }, 'forge-github: ghCommand must not be empty'],
|
|
[{ hosts: [] }, 'forge-github: hosts must list at least one host'],
|
|
[{ hosts: ['https://github.com'] }, 'forge-github: invalid host "https://github.com"'],
|
|
[{ timeoutMs: 0 }, 'forge-github: timeoutMs must be a positive integer no greater than 2147483647'],
|
|
[{ maxOutputBytes: 1.5 }, 'forge-github: maxOutputBytes must be a positive integer no greater than 2147483647'],
|
|
])('rejects %j at load', async (config, message) => {
|
|
const context = await forge()
|
|
|
|
await expect(context.plugin(ForgeGitHub, config)).rejects.toThrow(message)
|
|
})
|
|
})
|