@mastra/factory 0.2.1-alpha.3 → 0.2.1-alpha.4
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.
- package/CHANGELOG.md +14 -0
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +3462 -3583
- package/dist/factory.js.map +1 -1
- package/dist/index.js +3462 -3583
- package/dist/index.js.map +1 -1
- package/dist/integrations/base.d.ts +13 -25
- package/dist/integrations/base.d.ts.map +1 -1
- package/dist/integrations/github/integration.d.ts.map +1 -1
- package/dist/integrations/github/integration.js +625 -217
- package/dist/integrations/github/integration.js.map +1 -1
- package/dist/integrations/github/routes.d.ts +1 -4
- package/dist/integrations/github/routes.d.ts.map +1 -1
- package/dist/integrations/github/routes.js +113 -203
- package/dist/integrations/github/routes.js.map +1 -1
- package/dist/integrations/github/rules.d.ts +30 -0
- package/dist/integrations/github/rules.d.ts.map +1 -0
- package/dist/{rules/github-service.js → integrations/github/rules.js} +27 -8
- package/dist/integrations/github/rules.js.map +1 -0
- package/dist/integrations/linear/agent-tools.js.map +1 -1
- package/dist/integrations/linear/integration.d.ts.map +1 -1
- package/dist/integrations/linear/integration.js +352 -3
- package/dist/integrations/linear/integration.js.map +1 -1
- package/dist/integrations/linear/routes.d.ts +2 -2
- package/dist/integrations/linear/routes.d.ts.map +1 -1
- package/dist/integrations/linear/routes.js +2 -2
- package/dist/integrations/linear/routes.js.map +1 -1
- package/dist/integrations/linear/rules.d.ts +42 -0
- package/dist/integrations/linear/rules.d.ts.map +1 -0
- package/dist/{rules/linear-service.js → integrations/linear/rules.js} +14 -4
- package/dist/integrations/linear/rules.js.map +1 -0
- package/dist/integrations/platform/github/integration.d.ts.map +1 -1
- package/dist/integrations/platform/github/integration.js +626 -218
- package/dist/integrations/platform/github/integration.js.map +1 -1
- package/dist/integrations/platform/linear/integration.d.ts.map +1 -1
- package/dist/integrations/platform/linear/integration.js +353 -3
- package/dist/integrations/platform/linear/integration.js.map +1 -1
- package/dist/routes/oauth.js +6 -39
- package/dist/routes/oauth.js.map +1 -1
- package/dist/routes/surface.d.ts +3 -1
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +230 -619
- package/dist/routes/surface.js.map +1 -1
- package/dist/routes/work-items.js.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.js +74 -75
- package/dist/storage/domains/work-items/base.js.map +1 -1
- package/dist/storage/domains/work-items/metrics.js.map +1 -1
- package/package.json +7 -7
- package/dist/integrations/github/project-lock.d.ts +0 -100
- package/dist/integrations/github/project-lock.d.ts.map +0 -1
- package/dist/integrations/github/project-lock.js +0 -103
- package/dist/integrations/github/project-lock.js.map +0 -1
- package/dist/rules/github-service.d.ts +0 -29
- package/dist/rules/github-service.d.ts.map +0 -1
- package/dist/rules/github-service.js.map +0 -1
- package/dist/rules/linear-service.d.ts +0 -27
- package/dist/rules/linear-service.d.ts.map +0 -1
- package/dist/rules/linear-service.js.map +0 -1
|
@@ -29,10 +29,7 @@ export interface MountGithubRoutesOptions {
|
|
|
29
29
|
* respond 503.
|
|
30
30
|
*/
|
|
31
31
|
fleet: SandboxFleet;
|
|
32
|
-
/**
|
|
33
|
-
* Factory storage backend. Supplies the cross-replica `withDistributedLock`
|
|
34
|
-
* capability for git write routes and the `appDbConfigured` diagnostic.
|
|
35
|
-
*/
|
|
32
|
+
/** Factory storage backend used for the `appDbConfigured` diagnostic. */
|
|
36
33
|
storage?: FactoryStorage;
|
|
37
34
|
/**
|
|
38
35
|
* The GitHub App integration the handlers operate on (Octokit access, token
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/integrations/github/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,KAAK,EAAuD,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AASrF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/integrations/github/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,KAAK,EAAuD,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AASrF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAwC1D,OAAO,KAAK,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAgB/G,MAAM,WAAW,wBAAwB;IACvC,4EAA4E;IAC5E,IAAI,EAAE,SAAS,CAAC;IAChB;;;;OAIG;IACH,KAAK,EAAE,YAAY,CAAC;IACpB,yEAAyE;IACzE,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;OAIG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4FAA4F;IAC5F,UAAU,CAAC,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC7C,iEAAiE;IACjE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC3F,6EAA6E;IAC7E,SAAS,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IACjC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAClC,+FAA+F;IAC/F,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACvE;AAuPD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,QAAQ,EAAE,CA4oB/E"}
|
|
@@ -90,95 +90,8 @@ async function clearGithubPat(storage, orgId, kind = "default") {
|
|
|
90
90
|
await storage.settings.save(orgId, PAT_SETTINGS_USER_ID, rest);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
// src/integrations/github/project-lock.ts
|
|
94
|
-
import { createHash } from "crypto";
|
|
95
|
-
var inProcessLocks = /* @__PURE__ */ new Map();
|
|
96
|
-
var DEFAULT_PROJECT_LOCK_TIMEOUT_MS = 6e4;
|
|
97
|
-
var ProjectLockTimeoutError = class extends Error {
|
|
98
|
-
key;
|
|
99
|
-
timeoutMs;
|
|
100
|
-
constructor(key, timeoutMs) {
|
|
101
|
-
super(`Project lock critical section for "${key}" exceeded ${timeoutMs}ms`);
|
|
102
|
-
this.name = "ProjectLockTimeoutError";
|
|
103
|
-
this.key = key;
|
|
104
|
-
this.timeoutMs = timeoutMs;
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
async function runWithTimeout(key, timeoutMs, fn) {
|
|
108
|
-
const controller = new AbortController();
|
|
109
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
110
|
-
const abortError = new Promise((_, reject) => {
|
|
111
|
-
controller.signal.addEventListener("abort", () => reject(new ProjectLockTimeoutError(key, timeoutMs)), {
|
|
112
|
-
once: true
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
const work = fn(controller.signal);
|
|
116
|
-
work.catch(() => {
|
|
117
|
-
});
|
|
118
|
-
try {
|
|
119
|
-
return await Promise.race([work, abortError]);
|
|
120
|
-
} finally {
|
|
121
|
-
clearTimeout(timer);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
function hashKey(key) {
|
|
125
|
-
const digest = createHash("sha256").update(key).digest();
|
|
126
|
-
const a = digest.readInt32BE(0);
|
|
127
|
-
const b = digest.readInt32BE(4);
|
|
128
|
-
return [a, b];
|
|
129
|
-
}
|
|
130
|
-
function withProjectLock(options) {
|
|
131
|
-
const { key, storage, fn, pool, timeoutMs = DEFAULT_PROJECT_LOCK_TIMEOUT_MS } = options;
|
|
132
|
-
const prev = inProcessLocks.get(key) ?? Promise.resolve();
|
|
133
|
-
const run = () => withDbAdvisoryLock({ key, storage, fn, pool, timeoutMs });
|
|
134
|
-
const next = prev.then(run, run);
|
|
135
|
-
const tail = next.then(
|
|
136
|
-
() => void 0,
|
|
137
|
-
() => void 0
|
|
138
|
-
);
|
|
139
|
-
inProcessLocks.set(key, tail);
|
|
140
|
-
void tail.then(() => {
|
|
141
|
-
if (inProcessLocks.get(key) === tail) {
|
|
142
|
-
inProcessLocks.delete(key);
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
return next;
|
|
146
|
-
}
|
|
147
|
-
async function withDbAdvisoryLock(options) {
|
|
148
|
-
const { key, storage, fn, pool, timeoutMs = DEFAULT_PROJECT_LOCK_TIMEOUT_MS } = options;
|
|
149
|
-
if (process.env.MASTRACODE_DISTRIBUTED_LOCK === "0") {
|
|
150
|
-
return runWithTimeout(key, timeoutMs, fn);
|
|
151
|
-
}
|
|
152
|
-
if (pool) return advisoryLockOver(pool, key, timeoutMs, fn);
|
|
153
|
-
if (typeof storage?.withDistributedLock !== "function") {
|
|
154
|
-
return runWithTimeout(key, timeoutMs, fn);
|
|
155
|
-
}
|
|
156
|
-
return storage.withDistributedLock(key, () => runWithTimeout(key, timeoutMs, fn));
|
|
157
|
-
}
|
|
158
|
-
async function advisoryLockOver(pool, key, timeoutMs, fn) {
|
|
159
|
-
const [k1, k2] = hashKey(key);
|
|
160
|
-
const client = await pool.connect();
|
|
161
|
-
try {
|
|
162
|
-
await client.query("BEGIN");
|
|
163
|
-
await client.query("SELECT pg_advisory_xact_lock($1, $2)", [k1, k2]);
|
|
164
|
-
try {
|
|
165
|
-
const result = await runWithTimeout(key, timeoutMs, fn);
|
|
166
|
-
await client.query("COMMIT");
|
|
167
|
-
return result;
|
|
168
|
-
} catch (err) {
|
|
169
|
-
try {
|
|
170
|
-
await client.query("ROLLBACK");
|
|
171
|
-
} catch {
|
|
172
|
-
}
|
|
173
|
-
throw err;
|
|
174
|
-
}
|
|
175
|
-
} finally {
|
|
176
|
-
client.release();
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
93
|
// src/integrations/github/sandbox.ts
|
|
181
|
-
import { createHash
|
|
94
|
+
import { createHash } from "crypto";
|
|
182
95
|
function bindingStore(row, storage) {
|
|
183
96
|
return {
|
|
184
97
|
sandboxId: row.sandboxId,
|
|
@@ -374,7 +287,7 @@ var WorktreeError = class extends Error {
|
|
|
374
287
|
function safeBranchDir(branch) {
|
|
375
288
|
const sanitized = branch.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/\/+/g, "-").replace(/^[-.]+|[-.]+$/g, "").slice(0, 100) || "work";
|
|
376
289
|
if (sanitized === branch) return sanitized;
|
|
377
|
-
const hash =
|
|
290
|
+
const hash = createHash("sha256").update(branch).digest("hex").slice(0, 8);
|
|
378
291
|
return `${sanitized}-${hash}`;
|
|
379
292
|
}
|
|
380
293
|
function computeWorktreePath(repoWorkdir, branch) {
|
|
@@ -792,6 +705,20 @@ async function handleGithubWebhook(c, options) {
|
|
|
792
705
|
}
|
|
793
706
|
|
|
794
707
|
// src/integrations/github/routes.ts
|
|
708
|
+
var sessionOperationLocks = /* @__PURE__ */ new Map();
|
|
709
|
+
function withSessionOperationLock(sessionId, fn) {
|
|
710
|
+
const previous = sessionOperationLocks.get(sessionId) ?? Promise.resolve();
|
|
711
|
+
const next = previous.then(fn, fn);
|
|
712
|
+
const tail = next.then(
|
|
713
|
+
() => void 0,
|
|
714
|
+
() => void 0
|
|
715
|
+
);
|
|
716
|
+
sessionOperationLocks.set(sessionId, tail);
|
|
717
|
+
void tail.then(() => {
|
|
718
|
+
if (sessionOperationLocks.get(sessionId) === tail) sessionOperationLocks.delete(sessionId);
|
|
719
|
+
});
|
|
720
|
+
return next;
|
|
721
|
+
}
|
|
795
722
|
function loose(c) {
|
|
796
723
|
return c;
|
|
797
724
|
}
|
|
@@ -1476,7 +1403,7 @@ function buildGithubRoutes(options) {
|
|
|
1476
1403
|
}
|
|
1477
1404
|
})
|
|
1478
1405
|
);
|
|
1479
|
-
routes.push(...buildProjectGitRoutes({ github, auth, fleet,
|
|
1406
|
+
routes.push(...buildProjectGitRoutes({ github, auth, fleet, emitAudit }));
|
|
1480
1407
|
return routes;
|
|
1481
1408
|
}
|
|
1482
1409
|
async function loadOrgProject(options) {
|
|
@@ -1593,7 +1520,6 @@ function buildProjectGitRoutes({
|
|
|
1593
1520
|
github,
|
|
1594
1521
|
auth,
|
|
1595
1522
|
fleet,
|
|
1596
|
-
storage,
|
|
1597
1523
|
emitAudit
|
|
1598
1524
|
}) {
|
|
1599
1525
|
return [
|
|
@@ -1714,31 +1640,27 @@ function buildProjectGitRoutes({
|
|
|
1714
1640
|
}
|
|
1715
1641
|
const { workdir, sandboxBinding } = sessionWorkspace;
|
|
1716
1642
|
try {
|
|
1717
|
-
return await
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
metadata: { sessionId: sessionWorkspace.session.sessionId }
|
|
1737
|
-
}
|
|
1738
|
-
});
|
|
1739
|
-
}
|
|
1740
|
-
return c.json({ committed: result.committed });
|
|
1643
|
+
return await withSessionOperationLock(sessionWorkspace.session.sessionId, async () => {
|
|
1644
|
+
const sandbox = await resolveProjectSandbox({ fleet, sandboxRow: sandboxBinding });
|
|
1645
|
+
const result = await commitAll(
|
|
1646
|
+
sandbox,
|
|
1647
|
+
workdir,
|
|
1648
|
+
body.message,
|
|
1649
|
+
identityFromUser(await auth.ensureUser(loose(c)))
|
|
1650
|
+
);
|
|
1651
|
+
if (result.committed) {
|
|
1652
|
+
await emitAudit?.({
|
|
1653
|
+
context: loose(c),
|
|
1654
|
+
input: {
|
|
1655
|
+
action: "factory.git.commit",
|
|
1656
|
+
factoryProjectId: project.factoryProjectId,
|
|
1657
|
+
projectRepositoryId: project.id,
|
|
1658
|
+
targets: [{ type: "session", id: sessionWorkspace.session.sessionId }],
|
|
1659
|
+
metadata: { sessionId: sessionWorkspace.session.sessionId }
|
|
1660
|
+
}
|
|
1661
|
+
});
|
|
1741
1662
|
}
|
|
1663
|
+
return c.json({ committed: result.committed });
|
|
1742
1664
|
});
|
|
1743
1665
|
} catch (err) {
|
|
1744
1666
|
return gitErrorResponse(loose(c), err);
|
|
@@ -1769,29 +1691,25 @@ function buildProjectGitRoutes({
|
|
|
1769
1691
|
}
|
|
1770
1692
|
const { workdir, sandboxBinding } = sessionWorkspace;
|
|
1771
1693
|
try {
|
|
1772
|
-
return await
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
}
|
|
1792
|
-
});
|
|
1793
|
-
return c.json({ pushed: true, branch });
|
|
1794
|
-
}
|
|
1694
|
+
return await withSessionOperationLock(sessionWorkspace.session.sessionId, async () => {
|
|
1695
|
+
const sandbox = await resolveProjectSandbox({ fleet, sandboxRow: sandboxBinding });
|
|
1696
|
+
const access = await github.versionControl.getRepositoryAccess({
|
|
1697
|
+
orgId,
|
|
1698
|
+
repositoryId: project.repository.id
|
|
1699
|
+
});
|
|
1700
|
+
if (!access.authorization) throw new Error("Repository access did not include a bearer token.");
|
|
1701
|
+
await pushBranch(sandbox, workdir, branch, access.authorization.token, project.repository.slug);
|
|
1702
|
+
await emitAudit?.({
|
|
1703
|
+
context: loose(c),
|
|
1704
|
+
input: {
|
|
1705
|
+
action: "factory.git.push",
|
|
1706
|
+
factoryProjectId: project.factoryProjectId,
|
|
1707
|
+
projectRepositoryId: project.id,
|
|
1708
|
+
targets: [{ type: "branch", id: branch }],
|
|
1709
|
+
metadata: { branch, sessionId: sessionWorkspace.session.sessionId }
|
|
1710
|
+
}
|
|
1711
|
+
});
|
|
1712
|
+
return c.json({ pushed: true, branch });
|
|
1795
1713
|
});
|
|
1796
1714
|
} catch (err) {
|
|
1797
1715
|
return gitErrorResponse(loose(c), err);
|
|
@@ -1833,60 +1751,56 @@ function buildProjectGitRoutes({
|
|
|
1833
1751
|
return c.json({ error: "Invalid sessionId" }, 400);
|
|
1834
1752
|
}
|
|
1835
1753
|
try {
|
|
1836
|
-
return await
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1754
|
+
return await withSessionOperationLock(sessionWorkspace.session.sessionId, async () => {
|
|
1755
|
+
const result = await github.versionControl.createPullRequest({
|
|
1756
|
+
connection: {
|
|
1757
|
+
type: "app-installation",
|
|
1758
|
+
installationId: Number(project.installation.externalId)
|
|
1759
|
+
},
|
|
1760
|
+
sourceId: project.repository.slug,
|
|
1761
|
+
baseBranch: base,
|
|
1762
|
+
headBranch: head,
|
|
1763
|
+
title,
|
|
1764
|
+
body: prBody,
|
|
1765
|
+
actingUserId: userId
|
|
1766
|
+
});
|
|
1767
|
+
await emitAudit?.({
|
|
1768
|
+
context: loose(c),
|
|
1769
|
+
input: {
|
|
1770
|
+
action: "factory.git.pr_opened",
|
|
1771
|
+
factoryProjectId: project.factoryProjectId,
|
|
1772
|
+
projectRepositoryId: project.id,
|
|
1773
|
+
targets: [{ type: "pull_request", id: result.url, name: title }],
|
|
1774
|
+
metadata: { branch: head, base, url: result.url }
|
|
1775
|
+
}
|
|
1776
|
+
});
|
|
1777
|
+
const pullRequestNumber = pullRequestNumberFromUrl(result.url, project.repository.slug);
|
|
1778
|
+
if (pullRequestNumber) {
|
|
1779
|
+
const sessionId = sessionWorkspace.session.sessionId;
|
|
1780
|
+
await subscribeToPullRequest(
|
|
1781
|
+
{
|
|
1782
|
+
orgId,
|
|
1783
|
+
installationExternalId: project.installation.externalId,
|
|
1857
1784
|
projectRepositoryId: project.id,
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1785
|
+
repositoryExternalId: project.repository.externalId,
|
|
1786
|
+
repositorySlug: project.repository.slug,
|
|
1787
|
+
changeRequestId: pullRequestNumber.toString(),
|
|
1788
|
+
sessionId,
|
|
1789
|
+
ownerId: userId,
|
|
1790
|
+
resourceId: sessionId,
|
|
1791
|
+
threadId: sessionId,
|
|
1792
|
+
source: "factory-pr-create",
|
|
1793
|
+
subscribedByUserId: userId
|
|
1794
|
+
},
|
|
1795
|
+
github.integrationStorage
|
|
1796
|
+
).catch((error) => {
|
|
1797
|
+
console.warn(
|
|
1798
|
+
`[GitHub] Pull request ${result.url} was created but automatic subscription failed.`,
|
|
1799
|
+
error
|
|
1800
|
+
);
|
|
1861
1801
|
});
|
|
1862
|
-
const pullRequestNumber = pullRequestNumberFromUrl(result.url, project.repository.slug);
|
|
1863
|
-
if (pullRequestNumber) {
|
|
1864
|
-
const sessionId = sessionWorkspace.session.sessionId;
|
|
1865
|
-
await subscribeToPullRequest(
|
|
1866
|
-
{
|
|
1867
|
-
orgId,
|
|
1868
|
-
installationExternalId: project.installation.externalId,
|
|
1869
|
-
projectRepositoryId: project.id,
|
|
1870
|
-
repositoryExternalId: project.repository.externalId,
|
|
1871
|
-
repositorySlug: project.repository.slug,
|
|
1872
|
-
changeRequestId: pullRequestNumber.toString(),
|
|
1873
|
-
sessionId,
|
|
1874
|
-
ownerId: userId,
|
|
1875
|
-
resourceId: sessionId,
|
|
1876
|
-
threadId: sessionId,
|
|
1877
|
-
source: "factory-pr-create",
|
|
1878
|
-
subscribedByUserId: userId
|
|
1879
|
-
},
|
|
1880
|
-
github.integrationStorage
|
|
1881
|
-
).catch((error) => {
|
|
1882
|
-
console.warn(
|
|
1883
|
-
`[GitHub] Pull request ${result.url} was created but automatic subscription failed.`,
|
|
1884
|
-
error
|
|
1885
|
-
);
|
|
1886
|
-
});
|
|
1887
|
-
}
|
|
1888
|
-
return c.json({ url: result.url });
|
|
1889
1802
|
}
|
|
1803
|
+
return c.json({ url: result.url });
|
|
1890
1804
|
});
|
|
1891
1805
|
} catch (err) {
|
|
1892
1806
|
return c.json(
|
|
@@ -1906,24 +1820,20 @@ function buildProjectGitRoutes({
|
|
|
1906
1820
|
handler: async (c) => {
|
|
1907
1821
|
const owned = await loadOwnedProject({ github, auth, fleet, c: loose(c) });
|
|
1908
1822
|
if ("response" in owned) return owned.response;
|
|
1909
|
-
const {
|
|
1823
|
+
const { sandboxRow } = owned;
|
|
1910
1824
|
if (!sandboxRow.sandboxId) {
|
|
1911
1825
|
return c.json({ tornDown: false });
|
|
1912
1826
|
}
|
|
1913
1827
|
try {
|
|
1914
|
-
return await
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
sandbox
|
|
1924
|
-
});
|
|
1925
|
-
return c.json({ tornDown: true });
|
|
1926
|
-
}
|
|
1828
|
+
return await withSessionOperationLock(`sandbox:${sandboxRow.id}`, async () => {
|
|
1829
|
+
const sandbox = await fleet.reattachSandbox(sandboxRow.sandboxId);
|
|
1830
|
+
await teardownProjectSandbox({
|
|
1831
|
+
fleet,
|
|
1832
|
+
row: sandboxRow,
|
|
1833
|
+
storage: github.sourceControlStorage.sandboxes,
|
|
1834
|
+
sandbox
|
|
1835
|
+
});
|
|
1836
|
+
return c.json({ tornDown: true });
|
|
1927
1837
|
});
|
|
1928
1838
|
} catch (err) {
|
|
1929
1839
|
return gitErrorResponse(loose(c), err);
|