@dbx-tools/projen 0.9.5 → 0.9.7
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/README.md +69 -17
- package/index.ts +7 -5
- package/package.json +9 -6
- package/src/_rust-project.ts +356 -0
- package/src/_rust-release-workflow.ts +954 -0
- package/src/_rust-release.ts +605 -0
- package/src/_task-command.ts +89 -0
- package/src/barrels.ts +12 -11
- package/src/bun-app.ts +96 -85
- package/src/bun-workflow.ts +60 -52
- package/src/engine-root.ts +5 -5
- package/src/openapi.ts +16 -9
- package/src/packages.ts +9 -9
- package/src/pnpm-workspace.ts +1 -1
- package/src/project-js.ts +19 -25
- package/src/project-py.ts +28 -23
- package/src/project-rs.ts +100 -1098
- package/src/projen-version.ts +9 -0
- package/src/publish.ts +3 -4
- package/src/release-catalog.ts +1 -1
- package/src/release.ts +212 -177
- package/src/scaffold.ts +1 -1
- package/src/uniffi.ts +7 -0
- package/src/watch.ts +2 -2
- package/src/workspace-version.ts +20 -15
- package/tasks/barrels.ts +4 -4
- package/tasks/build-rust-release.ts +68 -0
- package/tasks/bump.ts +3 -2
- package/tasks/clean.ts +3 -3
- package/tasks/local-publish.ts +21 -3
- package/tasks/openapi.ts +2 -2
- package/tasks/publish-npm.ts +12 -6
- package/tasks/publish-python.ts +2 -2
- package/tasks/publish-uniffi-local.ts +11 -15
- package/tasks/publish.ts +88 -88
- package/tasks/python-registry.ts +1 -1
- package/tasks/release-bootstrap.ts +2 -2
- package/tasks/release-plan.ts +1 -1
- package/tasks/release-please.ts +1 -1
- package/tasks/release-pr.ts +60 -115
- package/tasks/release-request.ts +8 -29
- package/tasks/release-summary-units.ts +2 -9
- package/tasks/release-summary.ts +35 -24
- package/tasks/release-version.ts +44 -0
- package/tasks/rust-release.d.ts +41 -0
- package/tasks/rust-release.mjs +1717 -0
- package/tasks/sync.ts +3 -3
- package/tasks/uniffi-python.js +1 -1
- package/tasks/uniffi.ts +7 -1
- package/tasks/version-check.ts +6 -5
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Co-tested Projen release used by the engine and every generated project.
|
|
3
|
+
*
|
|
4
|
+
* The engine exposes Projen as a peer dependency so consumers and generated
|
|
5
|
+
* projects share one runtime instance. Keep the peer range and generated
|
|
6
|
+
* development dependency on this single value; duplicate Projen instances can
|
|
7
|
+
* break its remaining `instanceof`-based file detection.
|
|
8
|
+
*/
|
|
9
|
+
export const PROJEN_VERSION = "^0.103.27";
|
package/src/publish.ts
CHANGED
|
@@ -148,10 +148,9 @@ export function applyCompiledPublish(pkg: javascript.NodeProject): void {
|
|
|
148
148
|
const config = publishConfig(pkg);
|
|
149
149
|
if (config) pkg.package.addField("publishConfig", config);
|
|
150
150
|
|
|
151
|
-
// The
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
// bump task's local-registry publish.
|
|
151
|
+
// The workspace publisher compiles every selected package once and disables
|
|
152
|
+
// lifecycle scripts while packing. Keep `prepack` for a standalone package
|
|
153
|
+
// publish that did not pass through that workspace-level build.
|
|
155
154
|
if (!pkg.tasks.tryFind("prepack")) {
|
|
156
155
|
pkg.addTask("prepack", { description: "Compile before packing the published tarball" });
|
|
157
156
|
}
|
package/src/release-catalog.ts
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { createHash } from "node:crypto";
|
|
13
12
|
import { execFileSync } from "node:child_process";
|
|
13
|
+
import { createHash } from "node:crypto";
|
|
14
14
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
15
15
|
import { basename, join, relative, resolve } from "node:path";
|
|
16
16
|
import { Component, JsonFile, type Project } from "projen";
|
package/src/release.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** Unified default-branch release workflow generation. */
|
|
2
|
+
import { stringUtils } from "@dbx-tools/shared-core";
|
|
2
3
|
import { Component } from "projen";
|
|
3
4
|
import { GithubWorkflow } from "projen/lib/github";
|
|
4
5
|
import { JobPermission, type Job, type JobStep } from "projen/lib/github/workflows-model";
|
|
@@ -188,6 +189,12 @@ function verifyContextJob(tagPrefix: string, releaseBranch: string): Job {
|
|
|
188
189
|
"fetch-depth": 2,
|
|
189
190
|
},
|
|
190
191
|
},
|
|
192
|
+
{
|
|
193
|
+
name: "Setup Bun",
|
|
194
|
+
uses: "oven-sh/setup-bun@v2",
|
|
195
|
+
with: { "bun-version": BUN_VERSION },
|
|
196
|
+
},
|
|
197
|
+
{ name: "Install release validation dependencies", run: "bun install --frozen-lockfile" },
|
|
191
198
|
{
|
|
192
199
|
name: "Verify release context",
|
|
193
200
|
id: "release",
|
|
@@ -199,54 +206,52 @@ function verifyContextJob(tagPrefix: string, releaseBranch: string): Job {
|
|
|
199
206
|
"${{ github.event_name == 'workflow_dispatch' && inputs.expected_sha || '' }}",
|
|
200
207
|
DRY_RUN: "${{ github.event_name == 'workflow_dispatch' && inputs.dry_run || false }}",
|
|
201
208
|
},
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
"
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
`echo "release_version=\${RELEASE_TAG#${tagPrefix}}" >> "$GITHUB_OUTPUT"`,
|
|
249
|
-
].join("\n"),
|
|
209
|
+
// prettier-ignore
|
|
210
|
+
run: stringUtils.dedent(
|
|
211
|
+
// ============================================================================
|
|
212
|
+
/*bash*/`
|
|
213
|
+
if [ "$GITHUB_EVENT_NAME" = "push" ]; then
|
|
214
|
+
test "$GITHUB_REF_TYPE" = "branch"
|
|
215
|
+
test "$GITHUB_REF_NAME" = "${releaseBranch}"
|
|
216
|
+
RELEASE_SHA="$GITHUB_SHA"
|
|
217
|
+
test "$(git rev-parse HEAD)" = "$RELEASE_SHA"
|
|
218
|
+
RELEASE_VERSION="$(tr -d '\\r\\n' < VERSION)"
|
|
219
|
+
bun node_modules/@dbx-tools/projen/tasks/release-version.ts --version "$RELEASE_VERSION"
|
|
220
|
+
PREVIOUS_VERSION="$(git show "$RELEASE_SHA^:VERSION" | tr -d '\\r\\n')"
|
|
221
|
+
test "$PREVIOUS_VERSION" != "$RELEASE_VERSION"
|
|
222
|
+
RELEASE_TAG="${tagPrefix}$RELEASE_VERSION"
|
|
223
|
+
if git ls-remote --exit-code --tags origin "refs/tags/$RELEASE_TAG" >/dev/null 2>&1; then
|
|
224
|
+
git fetch --force origin "+refs/tags/$RELEASE_TAG:refs/tags/$RELEASE_TAG"
|
|
225
|
+
test "$(git cat-file -t "$RELEASE_TAG")" = "tag"
|
|
226
|
+
test "$(git rev-parse "$RELEASE_TAG^{commit}")" = "$RELEASE_SHA"
|
|
227
|
+
else
|
|
228
|
+
git fetch --force --tags origin
|
|
229
|
+
bun node_modules/@dbx-tools/projen/tasks/release-version.ts --version "$RELEASE_VERSION" --prefix ${JSON.stringify(tagPrefix)} --assert-next
|
|
230
|
+
git config user.name "github-actions[bot]"
|
|
231
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
232
|
+
git tag -a "$RELEASE_TAG" "$RELEASE_SHA" -m "$RELEASE_TAG"
|
|
233
|
+
git push origin "refs/tags/$RELEASE_TAG"
|
|
234
|
+
fi
|
|
235
|
+
else
|
|
236
|
+
case "$RELEASE_TAG" in ${tagPrefix}*) ;; *) exit 1 ;; esac
|
|
237
|
+
RELEASE_VERSION="\${RELEASE_TAG#${tagPrefix}}"
|
|
238
|
+
bun node_modules/@dbx-tools/projen/tasks/release-version.ts --version "$RELEASE_VERSION"
|
|
239
|
+
git fetch --force origin "+refs/tags/$RELEASE_TAG:refs/tags/$RELEASE_TAG"
|
|
240
|
+
test "$(git cat-file -t "$RELEASE_TAG")" = "tag"
|
|
241
|
+
RELEASE_SHA="$(git rev-parse "$RELEASE_TAG^{commit}")"
|
|
242
|
+
test "$(git rev-parse HEAD)" = "$RELEASE_SHA"
|
|
243
|
+
test "$RELEASE_SHA" = "$EXPECTED_SHA"
|
|
244
|
+
if [ -n "\${{ inputs.source_run_id }}" ]; then
|
|
245
|
+
case "\${{ inputs.stage }}" in node|python) ;; *) exit 1 ;; esac
|
|
246
|
+
case "\${{ inputs.source_run_id }}" in *[!0-9]*|"") exit 1 ;; esac
|
|
247
|
+
fi
|
|
248
|
+
fi
|
|
249
|
+
echo "release_tag=$RELEASE_TAG" >> "$GITHUB_OUTPUT"
|
|
250
|
+
echo "expected_sha=$RELEASE_SHA" >> "$GITHUB_OUTPUT"
|
|
251
|
+
echo "release_version=$RELEASE_VERSION" >> "$GITHUB_OUTPUT"
|
|
252
|
+
`
|
|
253
|
+
// ============================================================================
|
|
254
|
+
),
|
|
250
255
|
},
|
|
251
256
|
{
|
|
252
257
|
name: "Verify source artifact run",
|
|
@@ -257,15 +262,20 @@ function verifyContextJob(tagPrefix: string, releaseBranch: string): Job {
|
|
|
257
262
|
SOURCE_RUN_ID: "${{ inputs.source_run_id }}",
|
|
258
263
|
},
|
|
259
264
|
with: {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
265
|
+
// prettier-ignore
|
|
266
|
+
script: stringUtils.dedent(
|
|
267
|
+
// ============================================================================
|
|
268
|
+
/*js*/`
|
|
269
|
+
const run = await github.rest.actions.getWorkflowRun({
|
|
270
|
+
owner: context.repo.owner,
|
|
271
|
+
repo: context.repo.repo,
|
|
272
|
+
run_id: Number(process.env.SOURCE_RUN_ID),
|
|
273
|
+
});
|
|
274
|
+
if (run.data.path !== ".github/workflows/release.yml") core.setFailed("Source run is not release.yml");
|
|
275
|
+
if (run.data.head_sha !== process.env.EXPECTED_SHA) core.setFailed("Source run commit does not match the release tag");
|
|
276
|
+
`
|
|
277
|
+
// ============================================================================
|
|
278
|
+
),
|
|
269
279
|
},
|
|
270
280
|
},
|
|
271
281
|
],
|
|
@@ -423,44 +433,49 @@ function independentReleasePleaseJob(project: DBXToolsJavaScriptProject, branch:
|
|
|
423
433
|
RELEASE_PRS: "${{ steps.release.outputs.prs }}",
|
|
424
434
|
},
|
|
425
435
|
shell: "bash",
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
"
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
"
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
"
|
|
462
|
-
|
|
463
|
-
|
|
436
|
+
// prettier-ignore
|
|
437
|
+
run: stringUtils.dedent(
|
|
438
|
+
// ============================================================================
|
|
439
|
+
/*bash*/`
|
|
440
|
+
BRANCH="$(jq -r '.[0].headBranchName' <<<"$RELEASE_PRS")"
|
|
441
|
+
test -n "$BRANCH" && test "$BRANCH" != "null"
|
|
442
|
+
git fetch origin "$BRANCH"
|
|
443
|
+
git switch --force-create "$BRANCH" "origin/$BRANCH"
|
|
444
|
+
bun install
|
|
445
|
+
bunx projen
|
|
446
|
+
bun node_modules/@dbx-tools/projen/tasks/version-check.ts
|
|
447
|
+
bun node_modules/@dbx-tools/projen/tasks/release-plan.ts --base-ref origin/${branch}
|
|
448
|
+
bun node_modules/@dbx-tools/projen/tasks/release-summary-units.ts --from-ref origin/${branch}
|
|
449
|
+
if ! git diff --quiet || test -n "$(git ls-files --others --exclude-standard)"; then
|
|
450
|
+
git config user.name "github-actions[bot]"
|
|
451
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
452
|
+
git add -A
|
|
453
|
+
git commit -m "chore: reconcile release metadata"
|
|
454
|
+
git push origin "HEAD:$BRANCH"
|
|
455
|
+
fi
|
|
456
|
+
MERGED="false"
|
|
457
|
+
for ATTEMPT in $(seq 1 15); do
|
|
458
|
+
STATE="$(gh pr view "$BRANCH" --json state,mergeable --jq '[.state,.mergeable] | join(" ")')"
|
|
459
|
+
if [[ "$STATE" == MERGED* ]]; then MERGED="true"; break; fi
|
|
460
|
+
if [ "$STATE" = "OPEN CONFLICTING" ]; then
|
|
461
|
+
echo "::error::release pull request has merge conflicts"
|
|
462
|
+
exit 1
|
|
463
|
+
fi
|
|
464
|
+
if [ "$STATE" = "OPEN MERGEABLE" ] && gh pr merge "$BRANCH" --merge; then
|
|
465
|
+
MERGED="true"
|
|
466
|
+
break
|
|
467
|
+
fi
|
|
468
|
+
echo "release pull request is not mergeable yet (attempt $ATTEMPT/15)"
|
|
469
|
+
sleep 2
|
|
470
|
+
done
|
|
471
|
+
if [ "$MERGED" != "true" ]; then
|
|
472
|
+
echo "::error::release pull request did not become mergeable"
|
|
473
|
+
exit 1
|
|
474
|
+
fi
|
|
475
|
+
gh workflow run release.yml --ref "$RELEASE_BRANCH" -f automatic=true
|
|
476
|
+
`
|
|
477
|
+
// ============================================================================
|
|
478
|
+
),
|
|
464
479
|
},
|
|
465
480
|
],
|
|
466
481
|
};
|
|
@@ -500,22 +515,27 @@ function configureReleaseRequestWorkflow(
|
|
|
500
515
|
name: "Read release request",
|
|
501
516
|
id: "request",
|
|
502
517
|
shell: "bash",
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
"
|
|
508
|
-
"
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
"
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
518
|
+
// prettier-ignore
|
|
519
|
+
run: stringUtils.dedent(
|
|
520
|
+
// ============================================================================
|
|
521
|
+
/*bash*/`
|
|
522
|
+
MESSAGE="$(git log -1 --format=%B)"
|
|
523
|
+
if ! grep -q "^Release-Request: true$" <<<"$MESSAGE"; then
|
|
524
|
+
echo "requested=false" >> "$GITHUB_OUTPUT"
|
|
525
|
+
exit 0
|
|
526
|
+
fi
|
|
527
|
+
git fetch origin ${JSON.stringify(baseBranch)}
|
|
528
|
+
if git diff --quiet "origin/${baseBranch}...HEAD"; then
|
|
529
|
+
echo "requested=false" >> "$GITHUB_OUTPUT"
|
|
530
|
+
exit 0
|
|
531
|
+
fi
|
|
532
|
+
echo "requested=true" >> "$GITHUB_OUTPUT"
|
|
533
|
+
echo "branch=$GITHUB_REF_NAME" >> "$GITHUB_OUTPUT"
|
|
534
|
+
echo "notes_path=$(sed -n 's/^Release-Notes-Path: //p' <<<"$MESSAGE" | tail -1)" >> "$GITHUB_OUTPUT"
|
|
535
|
+
echo "title=$(git log -1 --skip=1 --format=%s)" >> "$GITHUB_OUTPUT"
|
|
536
|
+
`
|
|
537
|
+
// ============================================================================
|
|
538
|
+
),
|
|
519
539
|
},
|
|
520
540
|
{
|
|
521
541
|
name: "Create, merge, and release source pull request",
|
|
@@ -528,20 +548,25 @@ function configureReleaseRequestWorkflow(
|
|
|
528
548
|
NOTES_PATH: "${{ steps.request.outputs.notes_path }}",
|
|
529
549
|
},
|
|
530
550
|
shell: "bash",
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
"
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
551
|
+
// prettier-ignore
|
|
552
|
+
run: stringUtils.dedent(
|
|
553
|
+
// ============================================================================
|
|
554
|
+
/*bash*/`
|
|
555
|
+
test -f "$NOTES_PATH"
|
|
556
|
+
NOTES="$(cat "$NOTES_PATH")"
|
|
557
|
+
BODY="$(printf '## Release notes\\n\\n%s\\n' "$NOTES")"
|
|
558
|
+
PR="$(gh pr list --head "$SOURCE_BRANCH" --base "$BASE_BRANCH" --state open --json number --jq '.[0].number // empty')"
|
|
559
|
+
if [ -n "$PR" ]; then
|
|
560
|
+
gh pr edit "$PR" --title "$TITLE" --body "$BODY"
|
|
561
|
+
else
|
|
562
|
+
gh pr create --head "$SOURCE_BRANCH" --base "$BASE_BRANCH" --title "$TITLE" --body "$BODY"
|
|
563
|
+
PR="$(gh pr list --head "$SOURCE_BRANCH" --base "$BASE_BRANCH" --state open --json number --jq '.[0].number')"
|
|
564
|
+
fi
|
|
565
|
+
gh pr merge "$PR" --merge
|
|
566
|
+
gh workflow run release.yml --repo "$GITHUB_REPOSITORY" --ref "$BASE_BRANCH" -f automatic=true
|
|
567
|
+
`
|
|
568
|
+
// ============================================================================
|
|
569
|
+
),
|
|
545
570
|
},
|
|
546
571
|
],
|
|
547
572
|
});
|
|
@@ -673,20 +698,25 @@ function independentReleaseNotesJob(project: DBXToolsJavaScriptProject): Job {
|
|
|
673
698
|
{
|
|
674
699
|
name: "Remove consumed release notes",
|
|
675
700
|
shell: "bash",
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
"
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
701
|
+
// prettier-ignore
|
|
702
|
+
run: stringUtils.dedent(
|
|
703
|
+
// ============================================================================
|
|
704
|
+
/*bash*/`
|
|
705
|
+
git fetch origin ${JSON.stringify(projectReleaseBranch(project))}
|
|
706
|
+
if [ "$(git rev-parse origin/${projectReleaseBranch(project)})" != "$(git rev-parse HEAD)" ]; then
|
|
707
|
+
echo "::warning::main advanced before release-note cleanup; leaving temporary notes for the next release"
|
|
708
|
+
exit 0
|
|
709
|
+
fi
|
|
710
|
+
git rm -r --ignore-unmatch .release-notes
|
|
711
|
+
if ! git diff --cached --quiet; then
|
|
712
|
+
git config user.name "github-actions[bot]"
|
|
713
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
714
|
+
git commit -m "chore: remove consumed release notes"
|
|
715
|
+
git push origin "HEAD:${projectReleaseBranch(project)}"
|
|
716
|
+
fi
|
|
717
|
+
`
|
|
718
|
+
// ============================================================================
|
|
719
|
+
),
|
|
690
720
|
},
|
|
691
721
|
],
|
|
692
722
|
};
|
|
@@ -770,44 +800,49 @@ function addIndependentBranchSyncJob(
|
|
|
770
800
|
name: `Safely sync ${branch}`,
|
|
771
801
|
shell: "bash",
|
|
772
802
|
env: { SOURCE_BRANCH: branch, RELEASE_BRANCH: releaseBranch },
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
"
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
803
|
+
// prettier-ignore
|
|
804
|
+
run: stringUtils.dedent(
|
|
805
|
+
// ============================================================================
|
|
806
|
+
/*bash*/`
|
|
807
|
+
if ! git ls-remote --exit-code --heads origin "refs/heads/$SOURCE_BRANCH" >/dev/null 2>&1; then
|
|
808
|
+
echo "source branch $SOURCE_BRANCH no longer exists; nothing to sync"
|
|
809
|
+
exit 0
|
|
810
|
+
fi
|
|
811
|
+
git fetch origin "refs/heads/$SOURCE_BRANCH:refs/remotes/origin/$SOURCE_BRANCH"
|
|
812
|
+
git fetch origin "refs/heads/$RELEASE_BRANCH:refs/remotes/origin/$RELEASE_BRANCH"
|
|
813
|
+
if git merge-base --is-ancestor "origin/$SOURCE_BRANCH" "origin/$RELEASE_BRANCH"; then
|
|
814
|
+
git push origin "refs/remotes/origin/$RELEASE_BRANCH:refs/heads/$SOURCE_BRANCH"
|
|
815
|
+
elif git merge-base --is-ancestor "origin/$RELEASE_BRANCH" "origin/$SOURCE_BRANCH"; then
|
|
816
|
+
echo "source branch $SOURCE_BRANCH already contains released main"
|
|
817
|
+
else
|
|
818
|
+
git config user.name "github-actions[bot]"
|
|
819
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
820
|
+
git switch --force-create "$SOURCE_BRANCH" "origin/$SOURCE_BRANCH"
|
|
821
|
+
if git merge --no-ff --no-edit "origin/$RELEASE_BRANCH"; then
|
|
822
|
+
git push origin "HEAD:refs/heads/$SOURCE_BRANCH"
|
|
823
|
+
else
|
|
824
|
+
SAFE_GENERATED="true"
|
|
825
|
+
while IFS= read -r FILE; do
|
|
826
|
+
case "$FILE" in
|
|
827
|
+
.projen/release-units.json|.release-please-manifest.json|.release-units/*/source.json|.release-units/*/version.txt|.release-units/*/CHANGELOG.md|Cargo.lock|*/Cargo.toml|*/package.json|*/pyproject.toml|*/index.ts) ;;
|
|
828
|
+
*) SAFE_GENERATED="false" ;;
|
|
829
|
+
esac
|
|
830
|
+
done < <(git diff --name-only --diff-filter=U)
|
|
831
|
+
if [ "$SAFE_GENERATED" = "true" ] && bunx projen; then
|
|
832
|
+
git add -A
|
|
833
|
+
if [ -z "$(git diff --name-only --diff-filter=U)" ]; then
|
|
834
|
+
git commit --no-edit
|
|
835
|
+
git push origin "HEAD:refs/heads/$SOURCE_BRANCH"
|
|
836
|
+
exit 0
|
|
837
|
+
fi
|
|
838
|
+
fi
|
|
839
|
+
git merge --abort
|
|
840
|
+
echo "::warning::source branch $SOURCE_BRANCH has handwritten or unresolved conflicts with released main; leaving it untouched"
|
|
841
|
+
fi
|
|
842
|
+
fi
|
|
843
|
+
`
|
|
844
|
+
// ============================================================================
|
|
845
|
+
),
|
|
811
846
|
},
|
|
812
847
|
],
|
|
813
848
|
});
|
package/src/scaffold.ts
CHANGED
package/src/uniffi.ts
CHANGED
|
@@ -31,6 +31,13 @@ export const makeDefaultedInterfaceParametersOptional = (source: string): string
|
|
|
31
31
|
);
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
+
/** Remove UBRN's obsolete `*Interface` aliases once the `*Like` owner exists. */
|
|
35
|
+
export const removeObsoleteInterfaceAliases = (source: string): string =>
|
|
36
|
+
source.replace(
|
|
37
|
+
/\n\/\*\*\n \* @deprecated Use `\w+Like` instead\.\n \*\/\nexport type \w+Interface = \w+Like;\n/g,
|
|
38
|
+
"\n",
|
|
39
|
+
);
|
|
40
|
+
|
|
34
41
|
export interface TypeScriptBindingModule {
|
|
35
42
|
readonly specifier: string;
|
|
36
43
|
readonly source: string;
|
package/src/watch.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { isAbsolute, resolve } from "node:path";
|
|
19
19
|
import { watch as pathWatch } from "@dbx-tools/path";
|
|
20
|
-
import {
|
|
20
|
+
import { asyncUtils, log } from "@dbx-tools/shared-core";
|
|
21
21
|
import { isGeneratedFile, recordedRoots, repoRoot } from "./packages.ts";
|
|
22
22
|
|
|
23
23
|
const logger = log.logger("projen:watch");
|
|
@@ -132,7 +132,7 @@ export function watchLoop(
|
|
|
132
132
|
if (closing) return;
|
|
133
133
|
closing = true;
|
|
134
134
|
clearTimeout(timer);
|
|
135
|
-
await Promise.race([watcher.close().catch(() => {}),
|
|
135
|
+
await Promise.race([watcher.close().catch(() => {}), asyncUtils.sleep(CLOSE_GRACE_MS)]);
|
|
136
136
|
process.exit(code);
|
|
137
137
|
}
|
|
138
138
|
|
package/src/workspace-version.ts
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { chmodSync, existsSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
19
19
|
import { join } from "node:path";
|
|
20
|
-
import {
|
|
20
|
+
import { parse as parseVersion } from "semver";
|
|
21
|
+
import { captureTaskCommand } from "./_task-command.ts";
|
|
21
22
|
|
|
22
23
|
/** Name of the repo-root file holding the workspace version. */
|
|
23
24
|
export const VERSION_FILE = "VERSION";
|
|
@@ -33,10 +34,20 @@ export type Semver = [number, number, number];
|
|
|
33
34
|
/** Supported semantic release increments. */
|
|
34
35
|
export type VersionLevel = "patch" | "minor" | "major";
|
|
35
36
|
|
|
36
|
-
/** Parse `x.y.z
|
|
37
|
+
/** Parse an exact stable `x.y.z`, or `undefined` for prefixes, prereleases, or embedded versions. */
|
|
37
38
|
export function parseSemver(raw: string): Semver | undefined {
|
|
38
|
-
const
|
|
39
|
-
|
|
39
|
+
const value = raw.trim();
|
|
40
|
+
if (!SEMVER.test(value)) return undefined;
|
|
41
|
+
const parsed = parseVersion(value);
|
|
42
|
+
if (
|
|
43
|
+
!parsed ||
|
|
44
|
+
parsed.version !== value ||
|
|
45
|
+
parsed.prerelease.length > 0 ||
|
|
46
|
+
parsed.build.length > 0
|
|
47
|
+
) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
return [parsed.major, parsed.minor, parsed.patch];
|
|
40
51
|
}
|
|
41
52
|
|
|
42
53
|
/** Ordering comparator: negative when `a < b`, positive when `a > b`, zero when equal. */
|
|
@@ -66,7 +77,7 @@ export function readWorkspaceVersion(root: string): string {
|
|
|
66
77
|
const path = versionPath(root);
|
|
67
78
|
if (!existsSync(path)) return DEFAULT_VERSION;
|
|
68
79
|
const raw = readFileSync(path, "utf8").trim();
|
|
69
|
-
if (!
|
|
80
|
+
if (!parseSemver(raw)) {
|
|
70
81
|
throw new Error(`${VERSION_FILE} must contain an x.y.z version, got ${JSON.stringify(raw)}`);
|
|
71
82
|
}
|
|
72
83
|
return raw;
|
|
@@ -74,7 +85,7 @@ export function readWorkspaceVersion(root: string): string {
|
|
|
74
85
|
|
|
75
86
|
/** Write the workspace version to `<root>/VERSION`. Only `bump` and bootstrap call this. */
|
|
76
87
|
export function writeWorkspaceVersion(root: string, version: string): void {
|
|
77
|
-
if (!
|
|
88
|
+
if (!parseSemver(version)) {
|
|
78
89
|
throw new Error(`workspace version must be x.y.z, got ${JSON.stringify(version)}`);
|
|
79
90
|
}
|
|
80
91
|
writeFileSync(versionPath(root), `${version}\n`);
|
|
@@ -107,14 +118,7 @@ export function syncWorkspaceManifestVersion(manifestPath: string, version: stri
|
|
|
107
118
|
/** Run git in `cwd`, capturing stdout and swallowing failure (offline, no repo). */
|
|
108
119
|
function gitCapture(cwd: string, args: string[]): string {
|
|
109
120
|
try {
|
|
110
|
-
|
|
111
|
-
cwd,
|
|
112
|
-
stdout: "capture",
|
|
113
|
-
stderr: "ignore",
|
|
114
|
-
stdin: "ignore",
|
|
115
|
-
check: false,
|
|
116
|
-
});
|
|
117
|
-
return res.stdout?.trim() ?? "";
|
|
121
|
+
return captureTaskCommand(cwd, "git", args);
|
|
118
122
|
} catch {
|
|
119
123
|
return "";
|
|
120
124
|
}
|
|
@@ -131,7 +135,8 @@ export function latestTagVersion(cwd: string, prefix: string): Semver | undefine
|
|
|
131
135
|
`${prefix}*`,
|
|
132
136
|
]);
|
|
133
137
|
for (const tag of out.split("\n")) {
|
|
134
|
-
|
|
138
|
+
if (!tag.startsWith(prefix)) continue;
|
|
139
|
+
const v = parseSemver(tag.slice(prefix.length));
|
|
135
140
|
if (v) return v;
|
|
136
141
|
}
|
|
137
142
|
return undefined;
|