@xpertss/projen-types 0.0.21 → 0.0.22

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 (45) hide show
  1. package/.jsii +445 -309
  2. package/API.md +1453 -385
  3. package/README.md +40 -16
  4. package/lib/actions/action-build-workflow.js +1 -1
  5. package/lib/actions/action-dogfood-workflow.js +1 -1
  6. package/lib/actions/action-sonar-workflow.d.ts +10 -29
  7. package/lib/actions/action-sonar-workflow.js +9 -58
  8. package/lib/actions/github-action-project.d.ts +5 -22
  9. package/lib/actions/github-action-project.js +16 -12
  10. package/lib/cdk/app-runtime-scaffold.js +1 -1
  11. package/lib/cdk/cdk-app-project.js +1 -1
  12. package/lib/cdk/cdk-infra-project.js +1 -1
  13. package/lib/cdk/cdk-typescript-base.d.ts +3 -0
  14. package/lib/cdk/cdk-typescript-base.js +14 -2
  15. package/lib/cdk/components/ecr-ecs-constructs.js +1 -1
  16. package/lib/cdk/components/edge-networking-constructs.js +1 -1
  17. package/lib/cdk/database-component.js +1 -1
  18. package/lib/cdk/options.d.ts +2 -1
  19. package/lib/cdk/options.js +1 -1
  20. package/lib/common/projen-drift-check-workflow.js +1 -1
  21. package/lib/common/sonar-options.d.ts +29 -0
  22. package/lib/common/sonar-options.js +3 -0
  23. package/lib/common/sonar-workflow.d.ts +48 -0
  24. package/lib/common/sonar-workflow.js +75 -0
  25. package/lib/common/workflow-change-notice-workflow.js +1 -1
  26. package/lib/index.d.ts +2 -0
  27. package/lib/index.js +3 -1
  28. package/lib/java/components/cdk-deploy-hook.js +1 -1
  29. package/lib/java/components/code-index-workflow.js +1 -1
  30. package/lib/java/components/docker-publish.js +1 -1
  31. package/lib/java/components/flyway-migration.js +1 -1
  32. package/lib/java/components/github-packages-publish.js +1 -1
  33. package/lib/java/components/maven-central-publish.js +1 -1
  34. package/lib/java/components/maven-upgrade-report.js +1 -1
  35. package/lib/java/java-app-project.js +1 -1
  36. package/lib/java/java-library-project.js +1 -1
  37. package/lib/java/java-maven-base.d.ts +6 -2
  38. package/lib/java/java-maven-base.js +18 -14
  39. package/lib/java/java-service-project.js +1 -1
  40. package/lib/java/java-spring-boot-project.js +1 -1
  41. package/lib/java/maven/maven-module.js +1 -1
  42. package/lib/java/maven/maven-pom.js +1 -1
  43. package/lib/java/options.d.ts +2 -3
  44. package/lib/java/options.js +1 -1
  45. package/package.json +1 -1
package/.jsii CHANGED
@@ -106,7 +106,7 @@
106
106
  },
107
107
  "name": "@xpertss/projen-types",
108
108
  "readme": {
109
- "markdown": "# @xpertss/projen-types\n\nProjen project types for CDK/TypeScript and Java/Maven projects.\n\nInstead of hand-maintaining `pom.xml`, `cdk.json`, and GitHub workflows, you declare a project type in a `.projenrc.ts` file and let [projen](https://github.com/projen/projen) generate (and keep up to date) the whole scaffold: build files, source skeletons, CI workflows, and deploy pipelines.\n\n## Project types at a glance\n\n| Type | What it is | Publishes to | Generated workflows |\n| --- | --- | --- | --- |\n| `CdkInfraProject` | Pure-infrastructure CDK stacks (CloudFront, Route53, SQS, API Gateway, Cognito, ECR/ECS for externally-built images) | - | `build` (PR checks), `deploy` (manual dispatch) |\n| `CdkAppProject` | Full TypeScript service behind API Gateway: infra + app source + database | - | `build`, `deploy`, `app-build` (PR checks) |\n| `JavaMavenProject` | Plain Maven project, single- or multi-module, no framework | - | `build`, `upgrade` (nightly report) |\n| `JavaLibraryProject` | Reusable Java library | Maven Central | `build`, `upgrade` (nightly report), `publish-maven-central`, `codeindex` |\n| `JavaAppProject` | GUI/TUI/CLI Java application | GitHub Packages | `build`, `upgrade` (nightly report), `publish-ghpackages` |\n| `JavaSpringBootProject` | Spring Boot on Maven, single- or multi-module, **no Docker** | - | `build`, `upgrade` (nightly report) |\n| `JavaServiceProject` | Spring Boot service deployed as a container | Docker Hub | `build`, `upgrade` (nightly report), `publish-docker`, `deploy-cdk` |\n| `GitHubActionProject` | Reusable GitHub Action or Workflow | GitHub Releases | `build`, `test-dogfood`, `sonar`, `release` |\n\nThe Java types are layered, so pick the lowest layer that does what you need:\n\n```text\nJavaMavenProject java_maven Maven only; single- or multi-module; any supported Java line\n├── JavaLibraryProject java_library + Maven Central publish, source/javadoc jars, code index\n├── JavaAppProject java_app + GitHub Packages publish\n└── JavaSpringBootProject java_spring_boot + Spring Boot BOM and executable-jar repackaging; no Docker/Flyway/CDK\n └── JavaServiceProject java_service + Docker publish, Flyway, CDK deploy hook (single-module)\n```\n\nEvery Java type targets a configurable Java line (`javaVersion`: `1.8`, `17`, `21` or `25`; see [Java version support](#java-version-support)), and every one except `JavaServiceProject` can be a multi-module Maven reactor (see [JavaMavenProject](#javamavenproject)).\n\nOne foundation class is also exported for advanced use: `CdkTypescriptProject` (shared CDK + TypeScript base for the CDK types).\n\nAll project types:\n\n- run a **drift check** in PR builds - a job that re-runs projen and fails if generated files were hand-edited. Edit `.projenrc.ts`, then run `npx projen`; never edit generated files directly.\n- use the GitHub secret `PROJEN_GITHUB_TOKEN` (a fine-grained PAT) for projen's automation. Override with `gheTokenSecret`.\n- make all publishing/deploying **manual** (workflow_dispatch) rather than on every merge.\n\n## Getting started\n\nHow you start depends on what is already in the directory:\n\n| Starting point | Do this |\n| --- | --- |\n| Empty directory | `projen new --from` (below) |\n| Existing repo, no `.projenrc.ts` | `projen new --from ... --no-git` (below) |\n| A `.projenrc.ts` but no `.projen/` directory - copied from another repo, or one of the [examples](#examples) pasted into a fresh repo | [Starting from an existing `.projenrc.ts`](#starting-from-an-existing-projenrcts) |\n\nScaffold the repo with projen's own bootstrap, pointed at this package:\n\n```bash\nmkdir my-project && cd my-project\ngit init\nnpx projen new --from @xpertss/projen-types cdk_infra --name my-project\n```\n\nThat writes a starter `.projenrc.ts`, synthesizes the whole scaffold and\ninstalls dependencies. The type names `projen new` accepts are `cdk_infra`,\n`cdk_app`, `java_maven`, `java_library`, `java_app`, `java_spring_boot`,\n`java_service` and `git_hub_action`; pass a bogus one to have it list them.\nRequired options become flags: `--name` for every type, plus\n`--group-id`/`--artifact-id` (Java) and `--sonar-host-url`\n(`git_hub_action`). Any other plainly-typed option can be passed the same\nway - `--java-version 1.8`, `--cdk-deploy-target-repo owner/repo`,\n`--docker-registry ghcr.io`, `--no-use-flyway`, and so on. Modules can't be\npassed on the command line; add them to `.projenrc.ts` afterwards (see\n[JavaMavenProject](#javamavenproject)).\n\n**Adding projen to a repo that already has content.** `projen new` runs\n`git init` and commits the scaffold by default. In a repo with existing work,\npass `--no-git` so it writes the files and leaves committing to you:\n\n```bash\ncd existing-repo\nnpx projen new --from @xpertss/projen-types java_spring_boot --name obeya --group-id org.xpertss.obeya --artifact-id obeya-parent --no-git\n```\n\n**Commit a lockfile.** The generated `build.yml` and drift check install the\ntoolchain with `npm ci`, which needs a committed `package-lock.json`, and\n`projen new` doesn't always leave one behind. Run `npm install` once and\ncommit `package-lock.json` along with the scaffold. Without it those\nworkflows fail with an `::error::` that says exactly this. For the Java\ntypes, `package.json` is generated, and it pins `projen` and\n`@xpertss/projen-types` to **exact** versions (no `^`), so every machine and\nCI run uses the same generator. A floating range would make the drift check\nreport the differences between generator versions as drift.\n\nCommit the result. From then on, every change to the scaffold goes through\n`.projenrc.ts` followed by `npx projen`:\n\n```bash\nnpx projen\n```\n\nEvery type scaffolds from that one command; no option is *required* that\n`projen new` cannot pass. The structured options - `environments` and\n`GitHubActionProject`'s `dogfood` - are ones projen's CLI cannot render\ninto a projenrc, so they are added afterwards by editing `.projenrc.ts` and\nre-running `npx projen`. Leaving `environments` out simply generates no\ndeploy workflow; leaving `dogfood` out (or a service's\n`cdkDeployTargetRepo`) still generates the workflow, with one step that\nfails and tells you what to add - a gate this package considers load-bearing\nis allowed to be missing loudly, never silently.\n\nThe `name` option must match the `name` field in the project's `package.json` (for the CDK types). For the Java types it becomes the root pom's `<name>` and the generated `package.json` name.\n\n> **Never write projen's generated-file marker text literally in `.projenrc.ts`.** projen deletes, as an orphaned generated file, any file containing the marker line (`~~ Generated by projen. To modify, ...`), and that includes `.projenrc.ts` itself. When you generate a file yourself (for example with `TextFile`), insert the marker through the file's `marker` property: ``file.addLine(`# ${file.marker}`)``.\n\n## Starting from an existing `.projenrc.ts`\n\nA directory that has a `.projenrc.ts` but no `.projen/` directory has never\nbeen synthesized. This happens when you copy the rc from another repo, or paste\none of the [examples](#examples) into a fresh repo. In that state `npx projen`\nfails with:\n\n```\n👾 Unable to find projen project. Use \"projen new\" to create a new project.\n```\n\n`npx projen` doesn't run `.projenrc.ts` itself. It runs the `default` task\nlisted in `.projen/tasks.json`, and that file is written by the first synth.\nDo the first synth one of these two ways. After that, `npx projen` works as\nusual.\n\n**Option 1 (recommended): run `projen new` over the existing rc.** `projen\nnew` leaves an existing `.projenrc.ts` untouched and writes the rest of the\nscaffold, `.projen/` included. Pass the type and its required flags as you\nwould for a new repo. Their values don't have to match your rc, because the\n`npx projen` that follows re-synthesizes everything from the rc:\n\n```bash\nnpx projen new --from @xpertss/projen-types git_hub_action --name pull-request --sonar-host-url https://sonarcloud.io --no-git\nnpx projen\n```\n\nThe first command's output reflects only the flags. For example, a\n`GitHubActionProject`'s `test-dogfood.yml` is still the failing placeholder.\nThe second command applies everything in the rc (`dogfood`, `environments`,\nmodules, and so on).\n\n**Option 2 (Java types and `GitHubActionProject`): run the rc directly,\nonce.** The CDK types run their rc differently, so for those use option 1.\nInstall what the rc imports, give\nts-node a placeholder `tsconfig.projen.json` (the synth overwrites it with the\ngenerated one), and run the same command the generated `default` task runs:\n\n```bash\nnpm i -D projen @xpertss/projen-types constructs\necho '{}' > tsconfig.projen.json\nnpx -y -p ts-node@10.9.2 -p typescript@6.0.3 ts-node --project tsconfig.projen.json .projenrc.ts\nnpx projen\n```\n\nThe `echo` line works in bash and PowerShell. Don't drop `--project`: without\na tsconfig, ts-node fails on Node 22+ with `Unknown file extension \".ts\"`.\n\nEither way, commit `.projen/` along with the rest of the scaffold. A fresh\nclone then has its `tasks.json`, and `npx projen` works there straight away.\n\n## Updating an existing project when this package changes\n\nYour generated scaffold reflects the *installed* version of `@xpertss/projen-types` - `npx projen` reads your project type from the package in `node_modules`, not from this repository. So when this package ships a change (a bug fix, a new generated file, or altered workflow behavior), an existing project picks it up by bumping the dependency and re-synthesizing. A stale `node_modules` silently regenerates with the old behavior, so the bump is the load-bearing step.\n\nUsing the [`auto-commit` action](#githubactionproject) as a running example, say a new release adds the `# Purpose:` workflow header and SonarCloud wording. In the `auto-commit` repo:\n\n```bash\nnpm view @xpertss/projen-types version # what's the newest release?\nnpm i -D @xpertss/projen-types@latest # bump the installed project type\nnpx projen # re-synthesize every generated file\ngit diff # review before committing\n```\n\nThe diff here is the workflows gaining a `# Purpose:` comment and `sonar.yml` reflecting the SonarCloud wording. Commit the result with a normal `chore:` or `fix:` message - you never hand-edit the generated files themselves.\n\n## Examples\n\nEach example shows the `projen new` command first, then a fuller\n`.projenrc.ts`. Run the command first, then replace the generated\n`.projenrc.ts` with the example (or merge it in) and run `npx projen`. If you\npasted the example into a fresh repo first instead, see\n[Starting from an existing `.projenrc.ts`](#starting-from-an-existing-projenrcts).\n\n### CdkInfraProject\n\nPure infrastructure stacks with optional ECR/ECS and edge-networking constructs.\n\nScaffold it with the `cdk_infra` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types cdk_infra --name media-edge-infra\n```\n\n```typescript\n// .projenrc.ts\nimport { CdkInfraProject } from '@xpertss/projen-types';\n\nconst project = new CdkInfraProject({\n name: 'media-edge-infra',\n environments: [\n 'dev',\n { name: 'stage', accountId: '111111111111', region: 'eu-central-1' },\n { name: 'prod', accountId: '222222222222', region: 'eu-central-1', requiresApproval: true },\n ],\n edgeResources: ['cloudfront', 'route53', 'sqs'],\n ecrEcs: { enabled: true, externalImageSource: true },\n});\n\nproject.synth();\n```\n\nYou get:\n\n- `cdk.json`, `cdk synth` / `cdk diff` / `cdk deploy` tasks, and the standard `AwsCdkTypeScriptApp` layout (CDK 2.189.1 by default).\n- `.github/workflows/build.yml` - PR build that hard-fails on projen drift.\n- `.github/workflows/deploy.yml` - manual dispatch with one `deploy-<env>` job per environment (runs `cdk deploy --all` with `--context environment=<env>`); `requiresApproval` environments get a GitHub Environment approval gate.\n- `LICENSE` (MIT by default), `.editorconfig`, and the projen drift check.\n- `src/constructs/edge-networking.ts` - helper constructs only for the requested `edgeResources` (`cloudfront`, `route53`, `apigateway`, `cognito`, `sqs`).\n- `src/constructs/ecr-ecs.ts` when `ecrEcs.enabled` - ECR repo + Fargate service; `externalImageSource: true` (default) means the service pulls an image built outside this repo.\n\n### CdkAppProject\n\n`CdkInfraProject` plus application source, a database construct, and an app-level build workflow.\n\nScaffold it with the `cdk_app` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types cdk_app --name video-api\n```\n\n```typescript\n// .projenrc.ts\nimport { CdkAppProject } from '@xpertss/projen-types';\n\nconst project = new CdkAppProject({\n name: 'video-api',\n environments: ['dev', 'prod'],\n edgeResources: ['apigateway'],\n database: { engine: 'postgres', migrationTool: 'flyway' },\n appEntryPoint: 'src/app.ts',\n});\n\nproject.synth();\n```\n\nEverything from `CdkInfraProject`, plus:\n\n- `src/app.ts` - application entrypoint stub (`export function handler()`).\n- `src/handlers/example.ts` - API Gateway proxy handler stub, with `@types/aws-lambda` added as a dev dependency.\n- `src/constructs/database.ts` - a `Database` construct stub for the chosen engine (`postgres`/`mysql` -> RDS, `dynamodb` -> DynamoDB). `migrationTool` (no default, intentionally) is added as a dev dependency and referenced in the stub - wiring it up is left to you.\n- `.github/workflows/app-build.yml` - runs the project's test task on every PR, then checks for projen drift.\n\n### JavaMavenProject\n\nA plain Maven build with no framework and no publish target. It's the base of every other Java type, and it's usable on its own. It's single-module until you add a module, then it's a multi-module reactor.\n\nScaffold it with the `java_maven` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_maven --name legacy-tools --group-id org.xpertss --artifact-id legacy-tools --java-version 1.8\n```\n\n**Single module:**\n\n```typescript\n// .projenrc.ts\nimport { JavaMavenProject } from '@xpertss/projen-types';\n\nconst project = new JavaMavenProject({\n name: 'legacy-tools',\n groupId: 'org.xpertss',\n artifactId: 'legacy-tools',\n javaVersion: '1.8',\n});\n\nproject.addDependency('commons-io/commons-io@2.20.0'); // exact version\nproject.addTestDependency('org.assertj/assertj-core@3.27.3');\n\nproject.synth();\n```\n\n**Multi-module:** each `addModule()` call adds a module directory with its own generated `pom.xml`. The root pom becomes the `pom`-packaged reactor parent. Everything stays one projen project, with one `.projen/`, one `.gitignore` and one `tasks.json`.\n\n```typescript\n// .projenrc.ts\nimport { JavaMavenProject } from '@xpertss/projen-types';\n\nconst project = new JavaMavenProject({\n name: 'toolkit',\n groupId: 'org.xpertss.toolkit',\n artifactId: 'toolkit-parent',\n version: '0.1.0-SNAPSHOT',\n javaVersion: '17',\n});\n\nconst model = project.addModule({ dir: 'toolkit-model', artifactId: 'toolkit-model', description: 'Domain model' });\nconst stub = project.addModule({ dir: 'tools/stub-model', artifactId: 'toolkit-stub-model' }); // nested dirs are fine\nconst cli = project.addModule({ dir: 'toolkit-cli', artifactId: 'toolkit-cli' });\n\nstub.addModuleDependency(model); // sibling module: versionless\ncli.addModuleDependency(model);\ncli.addDependency('info.picocli/picocli@4.7.7'); // pinned: the version moves to the parent\ncli.addDependency('org.yaml/snakeyaml'); // versionless: managed below\nproject.addManagedDependency('org.yaml/snakeyaml@2.4');\nproject.addBom('org.testcontainers/testcontainers-bom@1.21.3');\n\nproject.synth();\n```\n\nWhat the reactor looks like:\n\n- **Root `pom.xml`:**\n - `<packaging>pom</packaging>`, with `<modules>` in `addModule` order.\n - `<dependencyManagement>` holds the BOM imports first (`type=pom`, `scope=import`), then every module at `${project.version}`, then every pinned version.\n - `<pluginManagement>` holds the plugin versions, and versionless `<plugins>` are inherited by every module: compiler, surefire, failsafe, jar, and enforcer.\n - `junit-jupiter` is a test dependency every module inherits. Its version comes from `junit-bom`, or from the Spring Boot BOM in the Spring Boot types.\n- **Module `pom.xml`:** `<parent>` with the right `relativePath` (`tools/stub-model` → `../../pom.xml`), then `artifactId`, `name`, `description`, and versionless `<dependencies>`. Nothing else, unless the module adds plugins.\n- A version given to `module.addDependency`/`addTestDependency`/`addPlugin` is moved into the parent's `<dependencyManagement>`/`<pluginManagement>`, so every module that uses an artifact gets the same version. Pinning one artifact at two different versions fails the synth.\n- The synth fails with a clear message on:\n - two modules with the same `artifactId`\n - two modules with the same `dir`, or one `dir` nested inside another\n - a `dir` outside the repo\n - a module depending on itself\n - `packaging` set to anything but `pom` on a project with modules\n\nYou get:\n\n- the root `pom.xml` (and one per module), written by this package:\n - **exact versions only**: a range such as `^1`, `~1.2` or `[1,2)` fails the synth\n - the compiler level, enforcer rule and JUnit line all follow `javaVersion`\n- one Maven run per build. `npx projen build` synthesizes, then runs `mvn -B verify`: compile, unit tests (surefire), package, and `*IT` integration tests (failsafe). There is no `mvn deploy` and no `dist/`.\n- `.github/workflows/build.yml`: a PR build that installs the pinned Node toolchain (`npm ci`) and the project's JDK (`actions/setup-java`, Maven cache), then runs `npx projen build`, plus a SonarQube step when `sonarProjectKey` is set. See [Adding CI jobs](#adding-ci-jobs-to-a-java-project).\n- `.github/workflows/upgrade.yml`: a nightly (03:00 UTC) **report** of available dependency and plugin updates in the job summary. It changes nothing, because every version comes from `.projenrc.ts`; apply an update there. Turn it off with `upgradeWorkflow: false`. The same report runs locally with `npx projen upgrade`.\n- the projen drift check, `LICENSE` (MIT by default), `.editorconfig`, and a generated `package.json` that pins the projen toolchain exactly.\n- no sample code, unless `sample: true` on a single-module project.\n\n### JavaLibraryProject\n\nA reusable Java library published to Maven Central.\n\nScaffold it with the `java_library` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_library --name common-utils --group-id org.xpertss --artifact-id common-utils\n```\n\n```typescript\n// .projenrc.ts\nimport { JavaLibraryProject } from '@xpertss/projen-types';\n\nconst project = new JavaLibraryProject({\n name: 'common-utils',\n groupId: 'org.xpertss',\n artifactId: 'common-utils',\n version: '1.0.0',\n sonarProjectKey: 'org.xpertss:common-utils',\n mavenCentralOidc: true,\n});\n\nproject.synth();\n```\n\nYou get everything from [`JavaMavenProject`](#javamavenproject), so modules work here too, plus:\n\n- `maven-source-plugin` and `maven-javadoc-plugin`, attaching the `-sources`/`-javadoc` jars Maven Central requires. In a multi-module library every module attaches them.\n- `.github/workflows/publish-maven-central.yml` - manual dispatch running `mvn -B deploy -P release`. With `mavenCentralOidc: true` it uses Maven Central's OIDC trusted publishing (no GPG secrets needed); otherwise it expects the secrets `MAVEN_GPG_PRIVATE_KEY`, `MAVEN_GPG_PASSPHRASE`, `MAVEN_CENTRAL_USERNAME`, `MAVEN_CENTRAL_PASSWORD`.\n- `.github/workflows/codeindex.yml` - on push to `main`, generates a Java source index under `.cai/` covering every module (disable with `publishCodeIndex: false`).\n\n### JavaSpringBootProject\n\nSpring Boot on Maven, single- or multi-module, **without** Docker, Flyway or a deploy hook. It's [`JavaMavenProject`](#javamavenproject) plus Spring Boot dependency management. Use it for a Spring Boot repo that ships something other than this package's container image, such as a multi-module control plane, or for a Boot app you deploy your own way.\n\nScaffold it with the `java_spring_boot` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_spring_boot --name obeya --group-id org.xpertss.obeya --artifact-id obeya-parent\n```\n\n```typescript\n// .projenrc.ts\nimport { JavaSpringBootProject } from '@xpertss/projen-types';\n\nconst project = new JavaSpringBootProject({\n name: 'obeya',\n groupId: 'org.xpertss.obeya',\n artifactId: 'obeya-parent',\n version: '0.1.0-SNAPSHOT',\n javaVersion: '21',\n copyrightOwner: 'Xpert Software',\n});\n\n// plain jar modules: shared libraries, clients, tools\nconst model = project.addModule({ dir: 'obeya-model', artifactId: 'obeya-model' });\nconst client = project.addModule({ dir: 'obeya-api-client', artifactId: 'obeya-api-client' });\nclient.addModuleDependency(model);\n\n// a Spring Boot application module, repackaged into an executable jar\nconst server = project.addSpringBootModule({ dir: 'obeya-server', artifactId: 'obeya-server' });\nserver.addModuleDependency(model);\nserver.addDependency('org.springframework.boot/spring-boot-starter-web'); // versionless: Boot's BOM manages it\nserver.addTestDependency('org.springframework.boot/spring-boot-starter-test');\n\nproject.addBom('org.testcontainers/testcontainers-bom@1.21.3');\n\nproject.synth();\n```\n\nYou get everything from [`JavaMavenProject`](#javamavenproject), plus:\n\n- `spring-boot-dependencies` imported as the **first** BOM, so starters and every library Boot manages (JUnit included) are added without a version. `springBootVersion` sets it; the default is the newest release of the line that supports `javaVersion` (see [Java version support](#java-version-support)).\n- `spring-boot-maven-plugin`, versioned in `<pluginManagement>`:\n - In a **single-module** project the root jar is repackaged into an executable jar.\n - In a **multi-module** project only modules added with `addSpringBootModule()` are repackaged; `addModule()` modules stay plain jars.\n - A repackaged module needs its `@SpringBootApplication` class before `mvn verify` passes, because `repackage` fails with `Unable to find main class` until one exists. Add a module as a plain `addModule()` while it's still empty.\n- failsafe configured to run integration tests against the compiled classes rather than the repackaged jar (as `spring-boot-starter-parent` does).\n- no starters, no Docker, no Flyway, no CDK. Add the starters you need with `addDependency`.\n\n### JavaServiceProject\n\nA Spring Boot service that publishes a Docker image and can trigger deploys in a companion CDK repo. It is [`JavaSpringBootProject`](#javaspringbootproject) plus Docker, Flyway and a deploy hook. It is **single-module**, because the Docker build, the migrations and the deploy hook all assume one deployable at the repo root; `addModule()` fails and points you to `JavaSpringBootProject`.\n\nScaffold it with the `java_service` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_service --name stream-processor --group-id org.xpertss --artifact-id stream-processor\n```\n\n```typescript\n// .projenrc.ts\nimport { JavaServiceProject } from '@xpertss/projen-types';\n\nconst project = new JavaServiceProject({\n name: 'stream-processor',\n groupId: 'org.xpertss',\n artifactId: 'stream-processor',\n dockerRegistry: 'docker.io/xpertss',\n cdkDeployTargetRepo: 'xpertss/stream-infra',\n environments: ['dev', { name: 'prod', requiresApproval: true }],\n});\n\nproject.synth();\n```\n\nYou get everything from [`JavaSpringBootProject`](#javaspringbootproject) (and so from `JavaMavenProject`), plus:\n\n- `spring-boot-starter-web` added to the pom (versionless; Boot's BOM manages it).\n- `.github/workflows/publish-docker.yml` - manual dispatch: `mvn -B package && docker build -t <registry>/<name>:<sha>`, logged in with the `DOCKER_USERNAME` / `DOCKER_PASSWORD` secrets. `dockerRegistry` defaults to `docker.io`.\n- Flyway wiring when `useFlyway` (default `true`): `flyway-core` (versionless, so it matches what Boot's Flyway auto-configuration expects), `flyway-maven-plugin` pinned for the Java line, and `src/main/resources/db/migration/V1__init.sql`.\n- `.github/workflows/deploy-cdk.yml` (the `CdkDeployHook`, generated by default) - manual dispatch with an environment selector; each job sends a `workflow_dispatch` to `deploy.yml` in the companion `cdkDeployTargetRepo` (a `CdkInfraProject`/`CdkAppProject` repo). With no `cdkDeployTargetRepo` set, the workflow is still generated but each job's only step fails with instructions - it is dispatch-only, so that lands on whoever tries to deploy rather than on every PR. Turn the workflow off entirely with `cdkDeployHook: false`. `environments` defaults to `['prod']`.\n\n### JavaAppProject\n\nA GUI/TUI/CLI Java application published to GitHub Packages only - no Maven Central, no Docker, no CDK deploy hook.\n\nScaffold it with the `java_app` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_app --name studio-cli --group-id org.xpertss --artifact-id studio-cli\n```\n\n```typescript\n// .projenrc.ts\nimport { JavaAppProject } from '@xpertss/projen-types';\n\nconst project = new JavaAppProject({\n name: 'studio-cli',\n groupId: 'org.xpertss',\n artifactId: 'studio-cli',\n ghPackagesRegistry: 'https://maven.pkg.github.com/xpertss/studio-cli',\n});\n\nproject.synth();\n```\n\nYou get everything from [`JavaMavenProject`](#javamavenproject) (modules included), plus `.github/workflows/publish-ghpackages.yml` - manual dispatch running `mvn -B deploy -DaltDeploymentRepository=github::<registry>`, authenticated with `GITHUB_TOKEN`. `ghPackagesRegistry` defaults to `https://maven.pkg.github.com/<repo>` derived from the repository URL.\n\n### GitHubActionProject\n\nA reusable GitHub Action or Workflow. This example scaffolds an action that stages a folder and, only if it changed, commits and pushes it.\n\nScaffold it with the `git_hub_action` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types git_hub_action --name auto-commit --sonar-host-url https://sonarcloud.io\n```\n\n```typescript\n// .projenrc.ts\nimport { GitHubActionProject } from '@xpertss/projen-types';\n\nconst project = new GitHubActionProject({\n name: 'auto-commit',\n description: 'Stage a folder and, only if it changed, commit and push it',\n sonarHostUrl: 'https://sonarcloud.io', // required, no default - your SonarCloud URL\n sonarOrganization: 'xpertss', // default - your SonarCloud org key\n dogfood: {\n // Two scenario steps: the \"changed\" path and the \"no-op\" path are both\n // load-bearing behavior for this action (a double-commit or a\n // push-when-empty bug is the failure mode a hand-rolled inline-shell\n // alternative is most likely to introduce).\n scenario: [\n {\n name: 'Changed path',\n fixtureSteps: [\n 'echo \"$(date -u +%Y%m%dT%H%M%SZ)\" >> test/fixtures/dogfood-state.txt',\n ],\n inputs: {\n commit_message: 'test: dogfood',\n branches: 'test/dogfood',\n },\n assertions: [\n // step id defaults to a slug of `name` - here \"changed-path-0\"\n '[ \"${{ steps.changed-path-0.outputs.committed }}\" = \"true\" ]',\n ],\n },\n {\n // No fixture change this time - nothing new to commit.\n name: 'No-op path',\n id: 'no-op-check', // pin an explicit id instead of relying on the default slug\n inputs: {\n commit_message: 'test: dogfood',\n branches: 'test/dogfood',\n },\n assertions: [\n '[ \"${{ steps.no-op-check.outputs.committed }}\" = \"false\" ]',\n ],\n },\n ],\n cleanup: [\n 'git push origin --delete test/dogfood || true',\n ],\n },\n});\n\nproject.synth();\n```\n\nYou get:\n\n- `action.yml` and `auto-commit.sh` are hand-written - this type only lints their content via `build.yml`'s shellcheck/yamllint/actionlint checks.\n- `.github/workflows/build.yml` - lint gate: `apt`-installed shellcheck/yamllint plus a pinned, SHA-256-verified `actionlint` release binary. Gates `main` alongside `sonar.yml`.\n- `.github/workflows/test-dogfood.yml` - runs the `dogfood.scenario` steps above against this repo's own `action.yml` (via `uses: ./`), then the shared `cleanup`, on `workflow_dispatch`, every `pull_request`, and nightly. Omit `dogfood` and the workflow still exists, with one step that fails on every PR until you declare a scenario - AD-001 allows a dogfood to be missing loudly, never silently. A *partial* `dogfood` (a scenario with no cleanup) is a synth error.\n- `.github/workflows/sonar.yml` - SonarCloud scan via the Scanner CLI (the quality gate blocks the PR), scanning `action.yml`/`.github/workflows/**`/`**/*.sh` explicitly.\n- `.github/workflows/release.yml` - `feat:`/`fix:` commits on `main` bump the version, tag `vX.Y.Z`, and create a GitHub Release.\n- `.github/workflows/projen-drift-check.yml` and `workflow-change-notice.yml` - drift detection and a change notice, always included.\n- `package.json` (**private**, version source only), `.yamllint`, `LICENSE` (MIT by default), and a `README.md` template - all regenerated by `npx projen`.\n\nNeeds the same two secrets as everything else in this package: `PROJEN_GITHUB_TOKEN` (used for automated PR comments) and `SONAR_TOKEN` (the Sonar scan). Onboard a brand-new action repo by running the `projen new` command above first (see [Getting started](#getting-started)), then replace the generated `.projenrc.ts` with the one above and run `npx projen`, then hand-write `action.yml`/`auto-commit.sh`/`test/fixtures/`. If you wrote the `.projenrc.ts` before running `projen new`, see [Starting from an existing `.projenrc.ts`](#starting-from-an-existing-projenrcts).\n\n## Java version support\n\n`javaVersion` picks the Java line a Java project targets. It defaults to `21`; the supported lines are `1.8` (alias `8`), `17`, `21` and `25`, and any other value fails the synth with that list. **Nothing in the generated build is hard-coded to one Java line.** Everything that depends on it comes from one table in this package, grouped by line:\n\n| | `1.8` | `17` | `21` | `25` |\n| --- | --- | --- | --- | --- |\n| Compiler level | `maven.compiler.source`/`target` = `1.8` (javac 8 has no `--release`) | `maven.compiler.release` = `17` | `release` = `21` | `release` = `25` |\n| Enforcer `requireJavaVersion` | `[1.8,)` | `[17,)` | `[21,)` | `[25,)` |\n| JUnit (`junit-bom`) | 5.14.4 (JUnit 6 needs Java 17) | 6.1.3 | 6.1.3 | 6.1.3 |\n| Default Spring Boot (`JavaSpringBootProject`) | 2.7.18 (Boot 3+ needs Java 17; a 3.x+ `springBootVersion` fails the synth) | 4.1.1 | 4.1.1 | 4.1.1 |\n| `flyway-maven-plugin` (`JavaServiceProject`) | 9.22.3 | 13.9.0 | 13.9.0 | 13.9.0 |\n| CI JDK (`actions/setup-java` `java-version`) | `8` | `17` | `21` | `25` |\n\nMaven plugins (the same on every line, because all of them run on JDK 8): `maven-compiler-plugin` 3.16.0, `maven-surefire-plugin`/`maven-failsafe-plugin` 3.6.0, `maven-jar-plugin` 3.5.1, `maven-enforcer-plugin` 3.6.3, `maven-source-plugin` 3.4.0 and `maven-javadoc-plugin` 3.12.0 (library only), `versions-maven-plugin` 2.22.0 (the `upgrade` report).\n\n**The enforcer.** `maven-enforcer-plugin` fails the build at the start when the JDK or Maven running it is older than the project needs. Without it you get confusing compiler errors later, or a jar built for the wrong runtime. Its Java rule always follows `javaVersion`. The Maven rule defaults to `[3.9,)`; change it with `minMavenVersion`, or drop the plugin entirely with `enforcer: false`. CI installs the matching JDK through `setup-java`, so the rule only fires on a developer machine with the wrong JDK. A Java 1.8 project builds on any newer JDK (the rule is a minimum), but the JDK 8 runtime API is guaranteed only when you build on JDK 8.\n\n**Overriding a version.** `pluginVersions` replaces any default in the table, keyed by `groupId/artifactId`, with an exact version:\n\n```typescript\nnew JavaMavenProject({\n name: 'svc',\n groupId: 'org.xpertss',\n artifactId: 'svc',\n pluginVersions: {\n 'org.apache.maven.plugins/maven-surefire-plugin': '3.5.6',\n 'org.junit/junit-bom': '5.14.4',\n },\n});\n```\n\n`project.pinnedVersion('org.apache.maven.plugins/maven-surefire-plugin')` returns the version in effect, for reuse in your own plugin config.\n\n**New Java lines** are one new row in this package's version table and a release. Until a line is listed, `javaVersion` rejects it rather than guessing.\n\n## Adding CI jobs to a Java project\n\n`build.yml` is exposed as `project.buildVerifyWorkflow`, so jobs are added through projen's `addJob` rather than `addOverride`. `project.ciSetupSteps` holds the steps every Maven job here needs: pinned Node, `npm ci`, and the project's JDK with a Maven cache. Every job in `build.yml` can then be made a required check on `main`.\n\n```typescript\nimport { github } from 'projen';\n\nproject.buildVerifyWorkflow.addJob('integration', {\n name: 'Container integration tests',\n runsOn: ['self-hosted', 'linux', 'fedora', 'podman'],\n permissions: { contents: github.workflows.JobPermission.READ },\n steps: [\n { name: 'Checkout', uses: 'actions/checkout@v7' },\n ...project.ciSetupSteps,\n { name: 'Integration tests', run: 'mvn -B verify -Pcontainer-its' },\n ],\n});\n```\n\n## Common options\n\nCDK project types (`CdkInfraProjectOptions` / `CdkAppProjectOptions`):\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `name` | - (required) | Project name; must match `package.json` |\n| `cdkVersion` | `2.189.1` | AWS CDK version |\n| `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |\n| `licensed` | `true` | Write a `LICENSE` |\n| `license` | `MIT` | SPDX identifier for the `LICENSE` |\n| `copyrightOwner` / `copyrightPeriod` | `Xpert Software` / current year | Named in the `LICENSE` |\n| `environments` | - (no `deploy` workflow) | Deploy targets for the `deploy` workflow; strings or `EnvironmentOptions` |\n| `ecrEcs` | - | `EcrEcsOptions` - `enabled`, `externalImageSource` (default `true`) |\n| `edgeResources` | - | Subset of `cloudfront`, `route53`, `apigateway`, `cognito`, `sqs` |\n| `database` | - (app only) | `DatabaseOptions` - `engine` (`postgres`/`mysql`/`dynamodb`, default `postgres`), `migrationTool` |\n| `appEntryPoint` | `src/app.ts` (app only) | Path of the generated application entrypoint |\n\nJava project types (`JavaMavenProjectOptions` and everything built on it - `JavaLibraryProjectOptions`, `JavaAppProjectOptions`, `JavaSpringBootProjectOptions`, `JavaServiceProjectOptions`):\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `name` | - (required) | Project name |\n| `groupId` | - (required) | Maven group id |\n| `artifactId` | - (required) | Maven artifact id (of the reactor parent, in a multi-module project) |\n| `version` | `0.1.0` | Maven version; must be exact |\n| `description` / `url` | - | Written to the root pom |\n| `javaVersion` | `21` | Java line: `1.8`, `17`, `21`, `25` - see [Java version support](#java-version-support) |\n| `javaDistribution` | `temurin` | `actions/setup-java` distribution for CI |\n| `packaging` | `jar` | Root packaging while the project has no modules; a project with modules is always `pom` |\n| `sample` | `false` | Starter `Main` + test under the `groupId` package (single-module only) |\n| `enforcer` | `true` | `maven-enforcer-plugin` with Maven and Java version rules |\n| `minMavenVersion` | `3.9` | The enforcer's `requireMavenVersion` minimum |\n| `pluginVersions` | - | Exact-version overrides for this package's defaults, keyed by `groupId/artifactId` |\n| `licensed` | `true` | Write a `LICENSE` |\n| `license` | `MIT` | SPDX identifier for the `LICENSE` |\n| `copyrightOwner` / `copyrightPeriod` | `Xpert Software` / current year | Named in the `LICENSE` |\n| `editorconfig` | `true` | Write a projen-managed `.editorconfig` (also on the CDK and action types) |\n| `upgradeWorkflow` | `true` | Generate the nightly update report (`upgrade.yml`) |\n| `sonarProjectKey` | - | SonarQube project key; the sonar step is skipped when unset |\n| `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |\n| `springBootVersion` | newest Boot for `javaVersion` (Spring Boot types only) | Exact Spring Boot version: the BOM and `spring-boot-maven-plugin` |\n| `cdkDeployTargetRepo` | - (service only; `deploy-cdk.yml` fails until set) | Companion CDK repo (`owner/repo`) whose `deploy.yml` the deploy hook dispatches |\n| `cdkDeployHook` | `true` (service only) | Whether to generate `deploy-cdk.yml` at all |\n| `dockerRegistry` | `docker.io` (service only) | Registry the Docker image is pushed to |\n| `useFlyway` | `true` (service only) | Flyway plugin/dependency + `V1__init.sql` |\n\nWith the default MIT license, the generated `LICENSE` looks like:\n\n```\nMIT License\n\nCopyright (c) 2024-2026 Xpert Software\n\nPermission is hereby granted, ...\n```\n\nThe header line (`MIT License`) is specific to the license type — an `Apache-2.0` project would instead show `Apache-2.0`.\n\nOverride the license type and copyright fields:\n\n```typescript\nnew JavaMavenProject({\n name: 'my-lib',\n groupId: 'org.xpertss',\n artifactId: 'my-lib',\n license: 'Apache-2.0', // any SPDX id projen ships a template for\n copyrightOwner: 'Xpert Software',\n copyrightPeriod: '2024-2026',\n});\n```\n\n`EnvironmentOptions` for deploy targets:\n\n```text\ninterface EnvironmentOptions {\n readonly name: string; // e.g. \"dev\", \"stage\", \"prod\"\n readonly accountId?: string; // AWS account id (CDK deploys)\n readonly region?: string; // AWS region (CDK deploys)\n readonly requiresApproval?: boolean; // GitHub Environment approval gate (default false)\n}\n```\n\nPlain strings (`'dev'`) are shorthand for `{ name: 'dev' }`.\n\n`GitHubActionProjectOptions`:\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `name` | - (required) | Project name |\n| `description` | - | One-line description; used in the default README template and recorded in the private `package.json` |\n| `sonarHostUrl` | - (required) | URL of your SonarCloud instance (e.g. `https://sonarcloud.io`); must be reachable from github.com-hosted runners |\n| `sonarOrganization` | `xpertss` | SonarCloud org key (`sonar.organization`); required by the Scanner CLI, not derived from the token |\n| `sonarTokenSecret` | `SONAR_TOKEN` | GitHub secret holding the Sonar token |\n| `sonarPullRequestGate` | `true` | Whether `sonar.yml` also runs on `pull_request` as a pass/fail gate |\n| `dogfood` | - (a `test-dogfood.yml` that fails until you declare one) | `ActionDogfoodOptions` - the scenario that exercises the action end-to-end via `uses: ./` |\n| `license` | `MIT` | SPDX identifier for the generated `LICENSE` |\n| `copyrightOwner` / `copyrightPeriod` | `Xpert Software` / current year | Named in the `LICENSE` |\n| `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT (drift-check PR comments); a dogfood that passes a `token` input must reference this secret in the step's `inputs` |\n\n`ActionDogfoodOptions`/`ActionDogfoodStep` - the dogfood scenario (`test-dogfood.yml`):\n\n```text\ninterface ActionDogfoodOptions {\n readonly scenario: ActionDogfoodStep[]; // one or more, run in order - required\n readonly cleanup: string[]; // shared, run once at the end with `if: always()` - required\n}\n\ninterface ActionDogfoodStep {\n readonly name: string; // labels this step-group's generated workflow steps\n readonly id?: string; // step id for the `uses: ./` call; default: a slug of `name`\n readonly fixtureSteps?: string[]; // shell, before the invocation (default: none)\n readonly inputs?: Record<string, string>; // `with:` for this invocation (default: none)\n readonly assertions: string[]; // shell, after the invocation - required; the step runs under set -euo pipefail so any failing line fails the job\n}\n```\n\nMost actions need exactly one `scenario` step. Actions with a re-run/no-op/idempotency behavior to verify (e.g. `auto-commit`'s no-op-on-no-change path, `create-pull-request`'s reuse-the-PR path) declare two - the second typically omits `fixtureSteps` so its invocation sees no new state, and its assertion checks the opposite outcome of the first. Reference an invocation's own outputs from a later assertion via `${{ steps.<id>.outputs.<name> }}`, using either the default slug or an explicit `id`.\n\n## Required GitHub secrets\n\n| Secret | Used by | Notes |\n| --- | --- | --- |\n| `PROJEN_GITHUB_TOKEN` | all types | PAT for projen's self-mutation/automation; override via `gheTokenSecret` |\n| `SONAR_TOKEN` | Java types with `sonarProjectKey`; `GitHubActionProject` | SonarQube scan step in `build.yml` / `sonar.yml`; override via `sonarTokenSecret` on `GitHubActionProject` |\n| `DOCKER_USERNAME` / `DOCKER_PASSWORD` | `JavaServiceProject` | Docker image push |\n| `MAVEN_GPG_PRIVATE_KEY`, `MAVEN_GPG_PASSPHRASE`, `MAVEN_CENTRAL_USERNAME`, `MAVEN_CENTRAL_PASSWORD` | `JavaLibraryProject` without `mavenCentralOidc` | Not needed with OIDC trusted publishing |\n\n## Customizing `.gitignore`\n\nEvery project type already ignores JetBrains IDE state (`/.idea/*`) and the `/spec/` directory with all of its subdirectories (local plans and specs, never committed). The Java types also ignore Maven `target/` output and Eclipse files. To ignore more, call the inherited `addGitIgnore()` method after constructing the project in your `.projenrc.ts`:\n\n```typescript\n// .projenrc.ts\nimport { CdkInfraProject } from '@xpertss/projen-types';\n\nconst project = new CdkInfraProject({\n name: 'my-infra',\n});\n\nproject.addGitIgnore('*.log');\nproject.addGitIgnore('.env.*');\nproject.addGitIgnore('/build/');\n\nproject.synth();\n```\n\nThe same works for every type - just swap the class (e.g. `JavaServiceProject`, `GitHubActionProject`). Each call takes one standard gitignore glob pattern. There is no `gitignore` constructor option: the project types' option interfaces do not expose one, so patterns go through `addGitIgnore()` instead.\n\nRe-run `npx projen` after editing - `.gitignore` is a generated file, so hand-editing it is caught by the drift check.\n\n## Troubleshooting\n\n**`Unable to find projen project. Use \"projen new\" to create a new project.`**\nIf the directory already has a `.projenrc.ts`, this error means the rc has\nnever been synthesized (there's no `.projen/tasks.json`), not that you need a\nnew project. See [Starting from an existing `.projenrc.ts`](#starting-from-an-existing-projenrcts).\n\n## Going further\n\nThe project types are composed from smaller components you can also attach to your own projects:\n\n| Component | Applies to | Purpose |\n| --- | --- | --- |\n| `AppRuntimeScaffold` | `NodeProject` | App source skeleton (`app.ts` + handlers) |\n| `DatabaseComponent` | `NodeProject` | Database construct stub + migration tool wiring |\n| `EcrEcsConstructs` | `Project` | ECR + Fargate ECS construct helper |\n| `EdgeNetworkingConstructs` | `Project` | Per-resource edge networking construct helpers |\n| `MavenPom` | `Project` | A `pom.xml` with modules, BOM imports, dependency/plugin management, and exact versions only |\n| `MavenModule` | `JavaMavenProject` | One module of a reactor (created by `addModule()`) |\n| `MavenUpgradeReport` | `GitHubProject` | Nightly report-only `upgrade.yml` |\n| `MavenCentralPublish` | `JavaMavenProject` | Manual-dispatch Maven Central publish workflow |\n| `DockerPublish` | `JavaMavenProject` | Manual-dispatch Docker build+push workflow |\n| `GitHubPackagesPublish` | `JavaMavenProject` | Manual-dispatch GitHub Packages publish workflow |\n| `FlywayMigration` | `JavaSpringBootProject` | Flyway plugin/dependency + migrations directory |\n| `CdkDeployHook` | `JavaMavenProject` | Manual-dispatch workflow that triggers `deploy.yml` in a companion CDK repo |\n| `CodeIndexWorkflow` | `JavaMavenProject` | Code index generation on push to `main` |\n| `ActionBuildWorkflow` | `GitHubProject` | The `lint` task (shellcheck/yamllint/pinned actionlint) + `build.yml` |\n| `ActionDogfoodWorkflow` | `GitHubProject` | `test-dogfood.yml` from an `ActionDogfoodOptions` scenario |\n| `ActionSonarWorkflow` | `GitHubProject` | `sonar.yml` (SonarCloud scan via the Scanner CLI) |\n\nExample - adding a Docker publish to a `JavaMavenProject` (`JavaServiceProject` is the packaged version of this, with Spring Boot):\n\n```typescript\nimport { DockerPublish, JavaMavenProject } from '@xpertss/projen-types';\n\nconst project = new JavaMavenProject({\n name: 'my-service',\n groupId: 'org.xpertss',\n artifactId: 'my-service',\n});\n\nnew DockerPublish(project, { dockerRegistry: 'ghcr.io' });\n\nproject.synth();\n```\n\nThe full API reference, including every option and property, is in [API.md](./API.md).\n"
109
+ "markdown": "# @xpertss/projen-types\n\nProjen project types for CDK/TypeScript and Java/Maven projects.\n\nInstead of hand-maintaining `pom.xml`, `cdk.json`, and GitHub workflows, you declare a project type in a `.projenrc.ts` file and let [projen](https://github.com/projen/projen) generate (and keep up to date) the whole scaffold: build files, source skeletons, CI workflows, and deploy pipelines.\n\n## Project types at a glance\n\n| Type | What it is | Publishes to | Generated workflows |\n| --- | --- | --- | --- |\n| `CdkInfraProject` | Pure-infrastructure CDK stacks (CloudFront, Route53, SQS, API Gateway, Cognito, ECR/ECS for externally-built images) | - | `build` (PR checks), `deploy` (manual dispatch) |\n| `CdkAppProject` | Full TypeScript service behind API Gateway: infra + app source + database | - | `build`, `deploy`, `app-build` (PR checks) |\n| `JavaMavenProject` | Plain Maven project, single- or multi-module, no framework | - | `build`, `upgrade` (nightly report) |\n| `JavaLibraryProject` | Reusable Java library | Maven Central | `build`, `upgrade` (nightly report), `publish-maven-central`, `codeindex` |\n| `JavaAppProject` | GUI/TUI/CLI Java application | GitHub Packages | `build`, `upgrade` (nightly report), `publish-ghpackages` |\n| `JavaSpringBootProject` | Spring Boot on Maven, single- or multi-module, **no Docker** | - | `build`, `upgrade` (nightly report) |\n| `JavaServiceProject` | Spring Boot service deployed as a container | Docker Hub | `build`, `upgrade` (nightly report), `publish-docker`, `deploy-cdk` |\n| `GitHubActionProject` | Reusable GitHub Action or Workflow | GitHub Releases | `build`, `test-dogfood`, `sonar`, `release` |\n\nThe Java types are layered, so pick the lowest layer that does what you need:\n\n```text\nJavaMavenProject java_maven Maven only; single- or multi-module; any supported Java line\n├── JavaLibraryProject java_library + Maven Central publish, source/javadoc jars, code index\n├── JavaAppProject java_app + GitHub Packages publish\n└── JavaSpringBootProject java_spring_boot + Spring Boot BOM and executable-jar repackaging; no Docker/Flyway/CDK\n └── JavaServiceProject java_service + Docker publish, Flyway, CDK deploy hook (single-module)\n```\n\nEvery Java type targets a configurable Java line (`javaVersion`: `1.8`, `17`, `21` or `25`; see [Java version support](#java-version-support)), and every one except `JavaServiceProject` can be a multi-module Maven reactor (see [JavaMavenProject](#javamavenproject)).\n\nOne foundation class is also exported for advanced use: `CdkTypescriptProject` (shared CDK + TypeScript base for the CDK types).\n\nAll project types:\n\n- run a **drift check** in PR builds - a job that re-runs projen and fails if generated files were hand-edited. Edit `.projenrc.ts`, then run `npx projen`; never edit generated files directly.\n- use the GitHub secret `PROJEN_GITHUB_TOKEN` (a fine-grained PAT) for projen's automation. Override with `gheTokenSecret`.\n- make all publishing/deploying **manual** (workflow_dispatch) rather than on every merge.\n- offer an opt-in SonarCloud scan (`sonar.yml`) on any type via `sonarHostUrl` (see [SonarCloud (opt-in)](#sonarcloud-opt-in)).\n\n## Getting started\n\nHow you start depends on what is already in the directory:\n\n| Starting point | Do this |\n| --- | --- |\n| Empty directory | `projen new --from` (below) |\n| Existing repo, no `.projenrc.ts` | `projen new --from ... --no-git` (below) |\n| A `.projenrc.ts` but no `.projen/` directory - copied from another repo, or one of the [examples](#examples) pasted into a fresh repo | [Starting from an existing `.projenrc.ts`](#starting-from-an-existing-projenrcts) |\n\nScaffold the repo with projen's own bootstrap, pointed at this package:\n\n```bash\nmkdir my-project && cd my-project\ngit init\nnpx projen new --from @xpertss/projen-types cdk_infra --name my-project\n```\n\nThat writes a starter `.projenrc.ts`, synthesizes the whole scaffold and\ninstalls dependencies. The type names `projen new` accepts are `cdk_infra`,\n`cdk_app`, `java_maven`, `java_library`, `java_app`, `java_spring_boot`,\n`java_service` and `git_hub_action`; pass a bogus one to have it list them.\nRequired options become flags: `--name` for every type, plus\n`--group-id`/`--artifact-id` (Java). Any other plainly-typed option can be\npassed the same way - `--sonar-host-url` (opt-in Sonar, all types),\n`--java-version 1.8`, `--cdk-deploy-target-repo owner/repo`,\n`--docker-registry ghcr.io`, `--no-use-flyway`, and so on. Modules can't be\npassed on the command line; add them to `.projenrc.ts` afterwards (see\n[JavaMavenProject](#javamavenproject)).\n\n**Adding projen to a repo that already has content.** `projen new` runs\n`git init` and commits the scaffold by default. In a repo with existing work,\npass `--no-git` so it writes the files and leaves committing to you:\n\n```bash\ncd existing-repo\nnpx projen new --from @xpertss/projen-types java_spring_boot --name obeya --group-id org.xpertss.obeya --artifact-id obeya-parent --no-git\n```\n\n**Commit a lockfile.** The generated `build.yml` and drift check install the\ntoolchain with `npm ci`, which needs a committed `package-lock.json`, and\n`projen new` doesn't always leave one behind. Run `npm install` once and\ncommit `package-lock.json` along with the scaffold. Without it those\nworkflows fail with an `::error::` that says exactly this. For the Java\ntypes, `package.json` is generated, and it pins `projen` and\n`@xpertss/projen-types` to **exact** versions (no `^`), so every machine and\nCI run uses the same generator. A floating range would make the drift check\nreport the differences between generator versions as drift.\n\nCommit the result. From then on, every change to the scaffold goes through\n`.projenrc.ts` followed by `npx projen`:\n\n```bash\nnpx projen\n```\n\nEvery type scaffolds from that one command; no option is *required* that\n`projen new` cannot pass. The structured options - `environments` and\n`GitHubActionProject`'s `dogfood` - are ones projen's CLI cannot render\ninto a projenrc, so they are added afterwards by editing `.projenrc.ts` and\nre-running `npx projen`. Leaving `environments` out simply generates no\ndeploy workflow; leaving `dogfood` out (or a service's\n`cdkDeployTargetRepo`) still generates the workflow, with one step that\nfails and tells you what to add - a gate this package considers load-bearing\nis allowed to be missing loudly, never silently.\n\nThe `name` option must match the `name` field in the project's `package.json` (for the CDK types). For the Java types it becomes the root pom's `<name>` and the generated `package.json` name.\n\n> **Never write projen's generated-file marker text literally in `.projenrc.ts`.** projen deletes, as an orphaned generated file, any file containing the marker line (`~~ Generated by projen. To modify, ...`), and that includes `.projenrc.ts` itself. When you generate a file yourself (for example with `TextFile`), insert the marker through the file's `marker` property: ``file.addLine(`# ${file.marker}`)``.\n\n## Starting from an existing `.projenrc.ts`\n\nA directory that has a `.projenrc.ts` but no `.projen/` directory has never\nbeen synthesized. This happens when you copy the rc from another repo, or paste\none of the [examples](#examples) into a fresh repo. In that state `npx projen`\nfails with:\n\n```\n👾 Unable to find projen project. Use \"projen new\" to create a new project.\n```\n\n`npx projen` doesn't run `.projenrc.ts` itself. It runs the `default` task\nlisted in `.projen/tasks.json`, and that file is written by the first synth.\nDo the first synth one of these two ways. After that, `npx projen` works as\nusual.\n\n**Option 1 (recommended): run `projen new` over the existing rc.** `projen\nnew` leaves an existing `.projenrc.ts` untouched and writes the rest of the\nscaffold, `.projen/` included. Pass the type and its required flags as you\nwould for a new repo. Their values don't have to match your rc, because the\n`npx projen` that follows re-synthesizes everything from the rc:\n\n```bash\nnpx projen new --from @xpertss/projen-types git_hub_action --name pull-request --sonar-host-url https://sonarcloud.io --no-git\nnpx projen\n```\n\nThe first command's output reflects only the flags. For example, a\n`GitHubActionProject`'s `test-dogfood.yml` is still the failing placeholder.\nThe second command applies everything in the rc (`dogfood`, `environments`,\nmodules, and so on).\n\n**Option 2 (Java types and `GitHubActionProject`): run the rc directly,\nonce.** The CDK types run their rc differently, so for those use option 1.\nInstall what the rc imports, give\nts-node a placeholder `tsconfig.projen.json` (the synth overwrites it with the\ngenerated one), and run the same command the generated `default` task runs:\n\n```bash\nnpm i -D projen @xpertss/projen-types constructs\necho '{}' > tsconfig.projen.json\nnpx -y -p ts-node@10.9.2 -p typescript@6.0.3 ts-node --project tsconfig.projen.json .projenrc.ts\nnpx projen\n```\n\nThe `echo` line works in bash and PowerShell. Don't drop `--project`: without\na tsconfig, ts-node fails on Node 22+ with `Unknown file extension \".ts\"`.\n\nEither way, commit `.projen/` along with the rest of the scaffold. A fresh\nclone then has its `tasks.json`, and `npx projen` works there straight away.\n\n## Updating an existing project when this package changes\n\nYour generated scaffold reflects the *installed* version of `@xpertss/projen-types` - `npx projen` reads your project type from the package in `node_modules`, not from this repository. So when this package ships a change (a bug fix, a new generated file, or altered workflow behavior), an existing project picks it up by bumping the dependency and re-synthesizing. A stale `node_modules` silently regenerates with the old behavior, so the bump is the load-bearing step.\n\nUsing the [`auto-commit` action](#githubactionproject) as a running example, say a new release adds the `# Purpose:` workflow header and SonarCloud wording. In the `auto-commit` repo:\n\n```bash\nnpm view @xpertss/projen-types version # what's the newest release?\nnpm i -D @xpertss/projen-types@latest # bump the installed project type\nnpx projen # re-synthesize every generated file\ngit diff # review before committing\n```\n\nThe diff here is the workflows gaining a `# Purpose:` comment and `sonar.yml` reflecting the SonarCloud wording. Commit the result with a normal `chore:` or `fix:` message - you never hand-edit the generated files themselves.\n\n## Examples\n\nEach example shows the `projen new` command first, then a fuller\n`.projenrc.ts`. Run the command first, then replace the generated\n`.projenrc.ts` with the example (or merge it in) and run `npx projen`. If you\npasted the example into a fresh repo first instead, see\n[Starting from an existing `.projenrc.ts`](#starting-from-an-existing-projenrcts).\n\n### CdkInfraProject\n\nPure infrastructure stacks with optional ECR/ECS and edge-networking constructs.\n\nScaffold it with the `cdk_infra` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types cdk_infra --name media-edge-infra\n```\n\n```typescript\n// .projenrc.ts\nimport { CdkInfraProject } from '@xpertss/projen-types';\n\nconst project = new CdkInfraProject({\n name: 'media-edge-infra',\n environments: [\n 'dev',\n { name: 'stage', accountId: '111111111111', region: 'eu-central-1' },\n { name: 'prod', accountId: '222222222222', region: 'eu-central-1', requiresApproval: true },\n ],\n edgeResources: ['cloudfront', 'route53', 'sqs'],\n ecrEcs: { enabled: true, externalImageSource: true },\n});\n\nproject.synth();\n```\n\nYou get:\n\n- `cdk.json`, `cdk synth` / `cdk diff` / `cdk deploy` tasks, and the standard `AwsCdkTypeScriptApp` layout (CDK 2.189.1 by default).\n- `.github/workflows/build.yml` - PR build that hard-fails on projen drift.\n- `.github/workflows/deploy.yml` - manual dispatch with one `deploy-<env>` job per environment (runs `cdk deploy --all` with `--context environment=<env>`); `requiresApproval` environments get a GitHub Environment approval gate.\n- `LICENSE` (MIT by default), `.editorconfig`, and the projen drift check.\n- `src/constructs/edge-networking.ts` - helper constructs only for the requested `edgeResources` (`cloudfront`, `route53`, `apigateway`, `cognito`, `sqs`).\n- `src/constructs/ecr-ecs.ts` when `ecrEcs.enabled` - ECR repo + Fargate service; `externalImageSource: true` (default) means the service pulls an image built outside this repo.\n\n### CdkAppProject\n\n`CdkInfraProject` plus application source, a database construct, and an app-level build workflow.\n\nScaffold it with the `cdk_app` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types cdk_app --name video-api\n```\n\n```typescript\n// .projenrc.ts\nimport { CdkAppProject } from '@xpertss/projen-types';\n\nconst project = new CdkAppProject({\n name: 'video-api',\n environments: ['dev', 'prod'],\n edgeResources: ['apigateway'],\n database: { engine: 'postgres', migrationTool: 'flyway' },\n appEntryPoint: 'src/app.ts',\n});\n\nproject.synth();\n```\n\nEverything from `CdkInfraProject`, plus:\n\n- `src/app.ts` - application entrypoint stub (`export function handler()`).\n- `src/handlers/example.ts` - API Gateway proxy handler stub, with `@types/aws-lambda` added as a dev dependency.\n- `src/constructs/database.ts` - a `Database` construct stub for the chosen engine (`postgres`/`mysql` -> RDS, `dynamodb` -> DynamoDB). `migrationTool` (no default, intentionally) is added as a dev dependency and referenced in the stub - wiring it up is left to you.\n- `.github/workflows/app-build.yml` - runs the project's test task on every PR, then checks for projen drift.\n\n### JavaMavenProject\n\nA plain Maven build with no framework and no publish target. It's the base of every other Java type, and it's usable on its own. It's single-module until you add a module, then it's a multi-module reactor.\n\nScaffold it with the `java_maven` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_maven --name legacy-tools --group-id org.xpertss --artifact-id legacy-tools --java-version 1.8\n```\n\n**Single module:**\n\n```typescript\n// .projenrc.ts\nimport { JavaMavenProject } from '@xpertss/projen-types';\n\nconst project = new JavaMavenProject({\n name: 'legacy-tools',\n groupId: 'org.xpertss',\n artifactId: 'legacy-tools',\n javaVersion: '1.8',\n});\n\nproject.addDependency('commons-io/commons-io@2.20.0'); // exact version\nproject.addTestDependency('org.assertj/assertj-core@3.27.3');\n\nproject.synth();\n```\n\n**Multi-module:** each `addModule()` call adds a module directory with its own generated `pom.xml`. The root pom becomes the `pom`-packaged reactor parent. Everything stays one projen project, with one `.projen/`, one `.gitignore` and one `tasks.json`.\n\n```typescript\n// .projenrc.ts\nimport { JavaMavenProject } from '@xpertss/projen-types';\n\nconst project = new JavaMavenProject({\n name: 'toolkit',\n groupId: 'org.xpertss.toolkit',\n artifactId: 'toolkit-parent',\n version: '0.1.0-SNAPSHOT',\n javaVersion: '17',\n});\n\nconst model = project.addModule({ dir: 'toolkit-model', artifactId: 'toolkit-model', description: 'Domain model' });\nconst stub = project.addModule({ dir: 'tools/stub-model', artifactId: 'toolkit-stub-model' }); // nested dirs are fine\nconst cli = project.addModule({ dir: 'toolkit-cli', artifactId: 'toolkit-cli' });\n\nstub.addModuleDependency(model); // sibling module: versionless\ncli.addModuleDependency(model);\ncli.addDependency('info.picocli/picocli@4.7.7'); // pinned: the version moves to the parent\ncli.addDependency('org.yaml/snakeyaml'); // versionless: managed below\nproject.addManagedDependency('org.yaml/snakeyaml@2.4');\nproject.addBom('org.testcontainers/testcontainers-bom@1.21.3');\n\nproject.synth();\n```\n\nWhat the reactor looks like:\n\n- **Root `pom.xml`:**\n - `<packaging>pom</packaging>`, with `<modules>` in `addModule` order.\n - `<dependencyManagement>` holds the BOM imports first (`type=pom`, `scope=import`), then every module at `${project.version}`, then every pinned version.\n - `<pluginManagement>` holds the plugin versions, and versionless `<plugins>` are inherited by every module: compiler, surefire, failsafe, jar, and enforcer.\n - `junit-jupiter` is a test dependency every module inherits. Its version comes from `junit-bom`, or from the Spring Boot BOM in the Spring Boot types.\n- **Module `pom.xml`:** `<parent>` with the right `relativePath` (`tools/stub-model` → `../../pom.xml`), then `artifactId`, `name`, `description`, and versionless `<dependencies>`. Nothing else, unless the module adds plugins.\n- A version given to `module.addDependency`/`addTestDependency`/`addPlugin` is moved into the parent's `<dependencyManagement>`/`<pluginManagement>`, so every module that uses an artifact gets the same version. Pinning one artifact at two different versions fails the synth.\n- The synth fails with a clear message on:\n - two modules with the same `artifactId`\n - two modules with the same `dir`, or one `dir` nested inside another\n - a `dir` outside the repo\n - a module depending on itself\n - `packaging` set to anything but `pom` on a project with modules\n\nYou get:\n\n- the root `pom.xml` (and one per module), written by this package:\n - **exact versions only**: a range such as `^1`, `~1.2` or `[1,2)` fails the synth\n - the compiler level, enforcer rule and JUnit line all follow `javaVersion`\n- one Maven run per build. `npx projen build` synthesizes, then runs `mvn -B verify`: compile, unit tests (surefire), package, and `*IT` integration tests (failsafe). There is no `mvn deploy` and no `dist/`.\n- `.github/workflows/build.yml`: a PR build that installs the pinned Node toolchain (`npm ci`) and the project's JDK (`actions/setup-java`, Maven cache), then runs `npx projen build`. The Maven build itself never runs a Sonar step - SonarCloud scanning is a separate, opt-in `sonar.yml` (set `sonarHostUrl`). See [Adding CI jobs](#adding-ci-jobs-to-a-java-project) and [SonarCloud (opt-in)](#sonarcloud-opt-in).\n- `.github/workflows/upgrade.yml`: a nightly (03:00 UTC) **report** of available dependency and plugin updates in the job summary. It changes nothing, because every version comes from `.projenrc.ts`; apply an update there. Turn it off with `upgradeWorkflow: false`. The same report runs locally with `npx projen upgrade`.\n- the projen drift check, `LICENSE` (MIT by default), `.editorconfig`, and a generated `package.json` that pins the projen toolchain exactly.\n- no sample code, unless `sample: true` on a single-module project.\n\n### JavaLibraryProject\n\nA reusable Java library published to Maven Central.\n\nScaffold it with the `java_library` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_library --name common-utils --group-id org.xpertss --artifact-id common-utils\n```\n\n```typescript\n// .projenrc.ts\nimport { JavaLibraryProject } from '@xpertss/projen-types';\n\nconst project = new JavaLibraryProject({\n name: 'common-utils',\n groupId: 'org.xpertss',\n artifactId: 'common-utils',\n version: '1.0.0',\n sonarHostUrl: 'https://sonarcloud.io', // opt-in: adds sonar.yml (see SonarCloud)\n mavenCentralOidc: true,\n});\n\nproject.synth();\n```\n\nYou get everything from [`JavaMavenProject`](#javamavenproject), so modules work here too, plus:\n\n- `maven-source-plugin` and `maven-javadoc-plugin`, attaching the `-sources`/`-javadoc` jars Maven Central requires. In a multi-module library every module attaches them.\n- `.github/workflows/publish-maven-central.yml` - manual dispatch running `mvn -B deploy -P release`. With `mavenCentralOidc: true` it uses Maven Central's OIDC trusted publishing (no GPG secrets needed); otherwise it expects the secrets `MAVEN_GPG_PRIVATE_KEY`, `MAVEN_GPG_PASSPHRASE`, `MAVEN_CENTRAL_USERNAME`, `MAVEN_CENTRAL_PASSWORD`.\n- `.github/workflows/codeindex.yml` - on push to `main`, generates a Java source index under `.cai/` covering every module (disable with `publishCodeIndex: false`).\n\n### JavaSpringBootProject\n\nSpring Boot on Maven, single- or multi-module, **without** Docker, Flyway or a deploy hook. It's [`JavaMavenProject`](#javamavenproject) plus Spring Boot dependency management. Use it for a Spring Boot repo that ships something other than this package's container image, such as a multi-module control plane, or for a Boot app you deploy your own way.\n\nScaffold it with the `java_spring_boot` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_spring_boot --name obeya --group-id org.xpertss.obeya --artifact-id obeya-parent\n```\n\n```typescript\n// .projenrc.ts\nimport { JavaSpringBootProject } from '@xpertss/projen-types';\n\nconst project = new JavaSpringBootProject({\n name: 'obeya',\n groupId: 'org.xpertss.obeya',\n artifactId: 'obeya-parent',\n version: '0.1.0-SNAPSHOT',\n javaVersion: '21',\n copyrightOwner: 'Xpert Software',\n});\n\n// plain jar modules: shared libraries, clients, tools\nconst model = project.addModule({ dir: 'obeya-model', artifactId: 'obeya-model' });\nconst client = project.addModule({ dir: 'obeya-api-client', artifactId: 'obeya-api-client' });\nclient.addModuleDependency(model);\n\n// a Spring Boot application module, repackaged into an executable jar\nconst server = project.addSpringBootModule({ dir: 'obeya-server', artifactId: 'obeya-server' });\nserver.addModuleDependency(model);\nserver.addDependency('org.springframework.boot/spring-boot-starter-web'); // versionless: Boot's BOM manages it\nserver.addTestDependency('org.springframework.boot/spring-boot-starter-test');\n\nproject.addBom('org.testcontainers/testcontainers-bom@1.21.3');\n\nproject.synth();\n```\n\nYou get everything from [`JavaMavenProject`](#javamavenproject), plus:\n\n- `spring-boot-dependencies` imported as the **first** BOM, so starters and every library Boot manages (JUnit included) are added without a version. `springBootVersion` sets it; the default is the newest release of the line that supports `javaVersion` (see [Java version support](#java-version-support)).\n- `spring-boot-maven-plugin`, versioned in `<pluginManagement>`:\n - In a **single-module** project the root jar is repackaged into an executable jar.\n - In a **multi-module** project only modules added with `addSpringBootModule()` are repackaged; `addModule()` modules stay plain jars.\n - A repackaged module needs its `@SpringBootApplication` class before `mvn verify` passes, because `repackage` fails with `Unable to find main class` until one exists. Add a module as a plain `addModule()` while it's still empty.\n- failsafe configured to run integration tests against the compiled classes rather than the repackaged jar (as `spring-boot-starter-parent` does).\n- no starters, no Docker, no Flyway, no CDK. Add the starters you need with `addDependency`.\n\n### JavaServiceProject\n\nA Spring Boot service that publishes a Docker image and can trigger deploys in a companion CDK repo. It is [`JavaSpringBootProject`](#javaspringbootproject) plus Docker, Flyway and a deploy hook. It is **single-module**, because the Docker build, the migrations and the deploy hook all assume one deployable at the repo root; `addModule()` fails and points you to `JavaSpringBootProject`.\n\nScaffold it with the `java_service` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_service --name stream-processor --group-id org.xpertss --artifact-id stream-processor\n```\n\n```typescript\n// .projenrc.ts\nimport { JavaServiceProject } from '@xpertss/projen-types';\n\nconst project = new JavaServiceProject({\n name: 'stream-processor',\n groupId: 'org.xpertss',\n artifactId: 'stream-processor',\n dockerRegistry: 'docker.io/xpertss',\n cdkDeployTargetRepo: 'xpertss/stream-infra',\n environments: ['dev', { name: 'prod', requiresApproval: true }],\n});\n\nproject.synth();\n```\n\nYou get everything from [`JavaSpringBootProject`](#javaspringbootproject) (and so from `JavaMavenProject`), plus:\n\n- `spring-boot-starter-web` added to the pom (versionless; Boot's BOM manages it).\n- `.github/workflows/publish-docker.yml` - manual dispatch: `mvn -B package && docker build -t <registry>/<name>:<sha>`, logged in with the `DOCKER_USERNAME` / `DOCKER_PASSWORD` secrets. `dockerRegistry` defaults to `docker.io`.\n- Flyway wiring when `useFlyway` (default `true`): `flyway-core` (versionless, so it matches what Boot's Flyway auto-configuration expects), `flyway-maven-plugin` pinned for the Java line, and `src/main/resources/db/migration/V1__init.sql`.\n- `.github/workflows/deploy-cdk.yml` (the `CdkDeployHook`, generated by default) - manual dispatch with an environment selector; each job sends a `workflow_dispatch` to `deploy.yml` in the companion `cdkDeployTargetRepo` (a `CdkInfraProject`/`CdkAppProject` repo). With no `cdkDeployTargetRepo` set, the workflow is still generated but each job's only step fails with instructions - it is dispatch-only, so that lands on whoever tries to deploy rather than on every PR. Turn the workflow off entirely with `cdkDeployHook: false`. `environments` defaults to `['prod']`.\n\n### JavaAppProject\n\nA GUI/TUI/CLI Java application published to GitHub Packages only - no Maven Central, no Docker, no CDK deploy hook.\n\nScaffold it with the `java_app` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_app --name studio-cli --group-id org.xpertss --artifact-id studio-cli\n```\n\n```typescript\n// .projenrc.ts\nimport { JavaAppProject } from '@xpertss/projen-types';\n\nconst project = new JavaAppProject({\n name: 'studio-cli',\n groupId: 'org.xpertss',\n artifactId: 'studio-cli',\n ghPackagesRegistry: 'https://maven.pkg.github.com/xpertss/studio-cli',\n});\n\nproject.synth();\n```\n\nYou get everything from [`JavaMavenProject`](#javamavenproject) (modules included), plus `.github/workflows/publish-ghpackages.yml` - manual dispatch running `mvn -B deploy -DaltDeploymentRepository=github::<registry>`, authenticated with `GITHUB_TOKEN`. `ghPackagesRegistry` defaults to `https://maven.pkg.github.com/<repo>` derived from the repository URL.\n\n### GitHubActionProject\n\nA reusable GitHub Action or Workflow. This example scaffolds an action that stages a folder and, only if it changed, commits and pushes it.\n\nScaffold it with the `git_hub_action` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types git_hub_action --name auto-commit --sonar-host-url https://sonarcloud.io\n```\n\n```typescript\n// .projenrc.ts\nimport { GitHubActionProject } from '@xpertss/projen-types';\n\nconst project = new GitHubActionProject({\n name: 'auto-commit',\n description: 'Stage a folder and, only if it changed, commit and push it',\n sonarHostUrl: 'https://sonarcloud.io', // optional - set it to add sonar.yml (see SonarCloud)\n sonarOrganization: 'xpertss', // default - your SonarCloud org key\n dogfood: {\n // Two scenario steps: the \"changed\" path and the \"no-op\" path are both\n // load-bearing behavior for this action (a double-commit or a\n // push-when-empty bug is the failure mode a hand-rolled inline-shell\n // alternative is most likely to introduce).\n scenario: [\n {\n name: 'Changed path',\n fixtureSteps: [\n 'echo \"$(date -u +%Y%m%dT%H%M%SZ)\" >> test/fixtures/dogfood-state.txt',\n ],\n inputs: {\n commit_message: 'test: dogfood',\n branches: 'test/dogfood',\n },\n assertions: [\n // step id defaults to a slug of `name` - here \"changed-path-0\"\n '[ \"${{ steps.changed-path-0.outputs.committed }}\" = \"true\" ]',\n ],\n },\n {\n // No fixture change this time - nothing new to commit.\n name: 'No-op path',\n id: 'no-op-check', // pin an explicit id instead of relying on the default slug\n inputs: {\n commit_message: 'test: dogfood',\n branches: 'test/dogfood',\n },\n assertions: [\n '[ \"${{ steps.no-op-check.outputs.committed }}\" = \"false\" ]',\n ],\n },\n ],\n cleanup: [\n 'git push origin --delete test/dogfood || true',\n ],\n },\n});\n\nproject.synth();\n```\n\nYou get:\n\n- `action.yml` and `auto-commit.sh` are hand-written - this type only lints their content via `build.yml`'s shellcheck/yamllint/actionlint checks.\n- `.github/workflows/build.yml` - lint gate: `apt`-installed shellcheck/yamllint plus a pinned, SHA-256-verified `actionlint` release binary. Gates `main` (alongside `sonar.yml` when Sonar is enabled).\n- `.github/workflows/test-dogfood.yml` - runs the `dogfood.scenario` steps above against this repo's own `action.yml` (via `uses: ./`), then the shared `cleanup`, on `workflow_dispatch`, every `pull_request`, and nightly. Omit `dogfood` and the workflow still exists, with one step that fails on every PR until you declare a scenario - AD-001 allows a dogfood to be missing loudly, never silently. A *partial* `dogfood` (a scenario with no cleanup) is a synth error.\n- `.github/workflows/sonar.yml` - SonarCloud scan via the Scanner CLI (the quality gate blocks the PR), scanning `action.yml`/`.github/workflows/**`/`**/*.sh` explicitly. Opt-in: generated only when `sonarHostUrl` is set (see [SonarCloud (opt-in)](#sonarcloud-opt-in)).\n- `.github/workflows/release.yml` - `feat:`/`fix:` commits on `main` bump the version, tag `vX.Y.Z`, and create a GitHub Release.\n- `.github/workflows/projen-drift-check.yml` and `workflow-change-notice.yml` - drift detection and a change notice, always included.\n- `package.json` (**private**, version source only), `.yamllint`, `LICENSE` (MIT by default), and a `README.md` template - all regenerated by `npx projen`.\n\nNeeds `PROJEN_GITHUB_TOKEN` (used for automated PR comments), and `SONAR_TOKEN` only when Sonar is enabled (see [SonarCloud (opt-in)](#sonarcloud-opt-in)). Onboard a brand-new action repo by running the `projen new` command above first (see [Getting started](#getting-started)), then replace the generated `.projenrc.ts` with the one above and run `npx projen`, then hand-write `action.yml`/`auto-commit.sh`/`test/fixtures/`. If you wrote the `.projenrc.ts` before running `projen new`, see [Starting from an existing `.projenrc.ts`](#starting-from-an-existing-projenrcts).\n\n## Java version support\n\n`javaVersion` picks the Java line a Java project targets. It defaults to `21`; the supported lines are `1.8` (alias `8`), `17`, `21` and `25`, and any other value fails the synth with that list. **Nothing in the generated build is hard-coded to one Java line.** Everything that depends on it comes from one table in this package, grouped by line:\n\n| | `1.8` | `17` | `21` | `25` |\n| --- | --- | --- | --- | --- |\n| Compiler level | `maven.compiler.source`/`target` = `1.8` (javac 8 has no `--release`) | `maven.compiler.release` = `17` | `release` = `21` | `release` = `25` |\n| Enforcer `requireJavaVersion` | `[1.8,)` | `[17,)` | `[21,)` | `[25,)` |\n| JUnit (`junit-bom`) | 5.14.4 (JUnit 6 needs Java 17) | 6.1.3 | 6.1.3 | 6.1.3 |\n| Default Spring Boot (`JavaSpringBootProject`) | 2.7.18 (Boot 3+ needs Java 17; a 3.x+ `springBootVersion` fails the synth) | 4.1.1 | 4.1.1 | 4.1.1 |\n| `flyway-maven-plugin` (`JavaServiceProject`) | 9.22.3 | 13.9.0 | 13.9.0 | 13.9.0 |\n| CI JDK (`actions/setup-java` `java-version`) | `8` | `17` | `21` | `25` |\n\nMaven plugins (the same on every line, because all of them run on JDK 8): `maven-compiler-plugin` 3.16.0, `maven-surefire-plugin`/`maven-failsafe-plugin` 3.6.0, `maven-jar-plugin` 3.5.1, `maven-enforcer-plugin` 3.6.3, `maven-source-plugin` 3.4.0 and `maven-javadoc-plugin` 3.12.0 (library only), `versions-maven-plugin` 2.22.0 (the `upgrade` report).\n\n**The enforcer.** `maven-enforcer-plugin` fails the build at the start when the JDK or Maven running it is older than the project needs. Without it you get confusing compiler errors later, or a jar built for the wrong runtime. Its Java rule always follows `javaVersion`. The Maven rule defaults to `[3.9,)`; change it with `minMavenVersion`, or drop the plugin entirely with `enforcer: false`. CI installs the matching JDK through `setup-java`, so the rule only fires on a developer machine with the wrong JDK. A Java 1.8 project builds on any newer JDK (the rule is a minimum), but the JDK 8 runtime API is guaranteed only when you build on JDK 8.\n\n**Overriding a version.** `pluginVersions` replaces any default in the table, keyed by `groupId/artifactId`, with an exact version:\n\n```typescript\nnew JavaMavenProject({\n name: 'svc',\n groupId: 'org.xpertss',\n artifactId: 'svc',\n pluginVersions: {\n 'org.apache.maven.plugins/maven-surefire-plugin': '3.5.6',\n 'org.junit/junit-bom': '5.14.4',\n },\n});\n```\n\n`project.pinnedVersion('org.apache.maven.plugins/maven-surefire-plugin')` returns the version in effect, for reuse in your own plugin config.\n\n**New Java lines** are one new row in this package's version table and a release. Until a line is listed, `javaVersion` rejects it rather than guessing.\n\n## Adding CI jobs to a Java project\n\n`build.yml` is exposed as `project.buildVerifyWorkflow`, so jobs are added through projen's `addJob` rather than `addOverride`. `project.ciSetupSteps` holds the steps every Maven job here needs: pinned Node, `npm ci`, and the project's JDK with a Maven cache. Every job in `build.yml` can then be made a required check on `main`.\n\n```typescript\nimport { github } from 'projen';\n\nproject.buildVerifyWorkflow.addJob('integration', {\n name: 'Container integration tests',\n runsOn: ['self-hosted', 'linux', 'fedora', 'podman'],\n permissions: { contents: github.workflows.JobPermission.READ },\n steps: [\n { name: 'Checkout', uses: 'actions/checkout@v7' },\n ...project.ciSetupSteps,\n { name: 'Integration tests', run: 'mvn -B verify -Pcontainer-its' },\n ],\n});\n```\n\n## Common options\n\nCDK project types (`CdkInfraProjectOptions` / `CdkAppProjectOptions`):\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `name` | - (required) | Project name; must match `package.json` |\n| `cdkVersion` | `2.189.1` | AWS CDK version |\n| `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |\n| `licensed` | `true` | Write a `LICENSE` |\n| `license` | `MIT` | SPDX identifier for the `LICENSE` |\n| `copyrightOwner` / `copyrightPeriod` | `Xpert Software` / current year | Named in the `LICENSE` |\n| `environments` | - (no `deploy` workflow) | Deploy targets for the `deploy` workflow; strings or `EnvironmentOptions` |\n| `ecrEcs` | - | `EcrEcsOptions` - `enabled`, `externalImageSource` (default `true`) |\n| `edgeResources` | - | Subset of `cloudfront`, `route53`, `apigateway`, `cognito`, `sqs` |\n| `database` | - (app only) | `DatabaseOptions` - `engine` (`postgres`/`mysql`/`dynamodb`, default `postgres`), `migrationTool` |\n| `appEntryPoint` | `src/app.ts` (app only) | Path of the generated application entrypoint |\n\nJava project types (`JavaMavenProjectOptions` and everything built on it - `JavaLibraryProjectOptions`, `JavaAppProjectOptions`, `JavaSpringBootProjectOptions`, `JavaServiceProjectOptions`):\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `name` | - (required) | Project name |\n| `groupId` | - (required) | Maven group id |\n| `artifactId` | - (required) | Maven artifact id (of the reactor parent, in a multi-module project) |\n| `version` | `0.1.0` | Maven version; must be exact |\n| `description` / `url` | - | Written to the root pom |\n| `javaVersion` | `21` | Java line: `1.8`, `17`, `21`, `25` - see [Java version support](#java-version-support) |\n| `javaDistribution` | `temurin` | `actions/setup-java` distribution for CI |\n| `packaging` | `jar` | Root packaging while the project has no modules; a project with modules is always `pom` |\n| `sample` | `false` | Starter `Main` + test under the `groupId` package (single-module only) |\n| `enforcer` | `true` | `maven-enforcer-plugin` with Maven and Java version rules |\n| `minMavenVersion` | `3.9` | The enforcer's `requireMavenVersion` minimum |\n| `pluginVersions` | - | Exact-version overrides for this package's defaults, keyed by `groupId/artifactId` |\n| `licensed` | `true` | Write a `LICENSE` |\n| `license` | `MIT` | SPDX identifier for the `LICENSE` |\n| `copyrightOwner` / `copyrightPeriod` | `Xpert Software` / current year | Named in the `LICENSE` |\n| `editorconfig` | `true` | Write a projen-managed `.editorconfig` (also on the CDK and action types) |\n| `upgradeWorkflow` | `true` | Generate the nightly update report (`upgrade.yml`) |\n| Sonar options | - | `sonarHostUrl`, `sonarOrganization`, `sonarTokenSecret`, `sonarPullRequestGate`, `sonarProjectKey` - SonarCloud is opt-in; see [SonarCloud (opt-in)](#sonarcloud-opt-in) |\n| `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |\n| `springBootVersion` | newest Boot for `javaVersion` (Spring Boot types only) | Exact Spring Boot version: the BOM and `spring-boot-maven-plugin` |\n| `cdkDeployTargetRepo` | - (service only; `deploy-cdk.yml` fails until set) | Companion CDK repo (`owner/repo`) whose `deploy.yml` the deploy hook dispatches |\n| `cdkDeployHook` | `true` (service only) | Whether to generate `deploy-cdk.yml` at all |\n| `dockerRegistry` | `docker.io` (service only) | Registry the Docker image is pushed to |\n| `useFlyway` | `true` (service only) | Flyway plugin/dependency + `V1__init.sql` |\n\nWith the default MIT license, the generated `LICENSE` looks like:\n\n```\nMIT License\n\nCopyright (c) 2024-2026 Xpert Software\n\nPermission is hereby granted, ...\n```\n\nThe header line (`MIT License`) is specific to the license type — an `Apache-2.0` project would instead show `Apache-2.0`.\n\nOverride the license type and copyright fields:\n\n```typescript\nnew JavaMavenProject({\n name: 'my-lib',\n groupId: 'org.xpertss',\n artifactId: 'my-lib',\n license: 'Apache-2.0', // any SPDX id projen ships a template for\n copyrightOwner: 'Xpert Software',\n copyrightPeriod: '2024-2026',\n});\n```\n\n`EnvironmentOptions` for deploy targets:\n\n```text\ninterface EnvironmentOptions {\n readonly name: string; // e.g. \"dev\", \"stage\", \"prod\"\n readonly accountId?: string; // AWS account id (CDK deploys)\n readonly region?: string; // AWS region (CDK deploys)\n readonly requiresApproval?: boolean; // GitHub Environment approval gate (default false)\n}\n```\n\nPlain strings (`'dev'`) are shorthand for `{ name: 'dev' }`.\n\n`GitHubActionProjectOptions`:\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `name` | - (required) | Project name |\n| `description` | - | One-line description; used in the default README template and recorded in the private `package.json` |\n| Sonar options | - | `sonarHostUrl`, `sonarOrganization`, `sonarTokenSecret`, `sonarPullRequestGate`, `sonarProjectKey` - SonarCloud is opt-in; see [SonarCloud (opt-in)](#sonarcloud-opt-in) |\n| `dogfood` | - (a `test-dogfood.yml` that fails until you declare one) | `ActionDogfoodOptions` - the scenario that exercises the action end-to-end via `uses: ./` |\n| `license` | `MIT` | SPDX identifier for the generated `LICENSE` |\n| `copyrightOwner` / `copyrightPeriod` | `Xpert Software` / current year | Named in the `LICENSE` |\n| `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT (drift-check PR comments); a dogfood that passes a `token` input must reference this secret in the step's `inputs` |\n\n`ActionDogfoodOptions`/`ActionDogfoodStep` - the dogfood scenario (`test-dogfood.yml`):\n\n```text\ninterface ActionDogfoodOptions {\n readonly scenario: ActionDogfoodStep[]; // one or more, run in order - required\n readonly cleanup: string[]; // shared, run once at the end with `if: always()` - required\n}\n\ninterface ActionDogfoodStep {\n readonly name: string; // labels this step-group's generated workflow steps\n readonly id?: string; // step id for the `uses: ./` call; default: a slug of `name`\n readonly fixtureSteps?: string[]; // shell, before the invocation (default: none)\n readonly inputs?: Record<string, string>; // `with:` for this invocation (default: none)\n readonly assertions: string[]; // shell, after the invocation - required; the step runs under set -euo pipefail so any failing line fails the job\n}\n```\n\nMost actions need exactly one `scenario` step. Actions with a re-run/no-op/idempotency behavior to verify (e.g. `auto-commit`'s no-op-on-no-change path, `create-pull-request`'s reuse-the-PR path) declare two - the second typically omits `fixtureSteps` so its invocation sees no new state, and its assertion checks the opposite outcome of the first. Reference an invocation's own outputs from a later assertion via `${{ steps.<id>.outputs.<name> }}`, using either the default slug or an explicit `id`.\n\n## SonarCloud (opt-in)\n\nSonarCloud is a shared, **opt-in** capability on every project type (CDK, Java, and GitHub Action). Set `sonarHostUrl` on any type and it generates a `.github/workflows/sonar.yml` that runs a pinned, SHA-256-verified Sonar Scanner CLI and blocks the PR on the quality gate. Omit it and no `sonar.yml` is generated. The Maven build itself never runs a Sonar step.\n\nShared options (accepted by the CDK types, every Java type, and `GitHubActionProject`):\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `sonarHostUrl` | - (required to enable) | URL of your SonarCloud instance (e.g. `https://sonarcloud.io`); must be reachable from github.com-hosted runners |\n| `sonarOrganization` | `xpertss` | SonarCloud org key (`sonar.organization`); required by the Scanner CLI, not derived from the token |\n| `sonarProjectKey` | `${sonarOrganization}_${name}` | `sonar.projectKey` - the org + project key SonarCloud uses (e.g. `xpertss_create-pull-request`) |\n| `sonarTokenSecret` | `SONAR_TOKEN` | GitHub secret holding the Sonar token |\n| `sonarPullRequestGate` | `true` | Whether `sonar.yml` also runs on `pull_request` as a pass/fail gate |\n\nInclusions differ by type: a `GitHubActionProject` scans `action.yml`/`.github/workflows/**`/`**/*.sh` explicitly (YAML and shell are not in Sonar's default-recognized set), while the CDK and Java types rely on Sonar's default inclusions for their languages.\n\n```typescript\nnew CdkInfraProject({\n name: 'my-infra',\n environments: ['dev', 'prod'],\n sonarHostUrl: 'https://sonarcloud.io', // adds sonar.yml\n});\n```\n\nRequires the `SONAR_TOKEN` secret (rename it with `sonarTokenSecret`).\n\n## Required GitHub secrets\n\n| Secret | Used by | Notes |\n| --- | --- | --- |\n| `PROJEN_GITHUB_TOKEN` | all types | PAT for projen's self-mutation/automation; override via `gheTokenSecret` |\n| `SONAR_TOKEN` | any type with `sonarHostUrl` set | SonarCloud scan in `sonar.yml`; override the secret name via `sonarTokenSecret` |\n| `DOCKER_USERNAME` / `DOCKER_PASSWORD` | `JavaServiceProject` | Docker image push |\n| `MAVEN_GPG_PRIVATE_KEY`, `MAVEN_GPG_PASSPHRASE`, `MAVEN_CENTRAL_USERNAME`, `MAVEN_CENTRAL_PASSWORD` | `JavaLibraryProject` without `mavenCentralOidc` | Not needed with OIDC trusted publishing |\n\n## Customizing `.gitignore`\n\nEvery project type already ignores JetBrains IDE state (`/.idea/*`) and the `/spec/` directory with all of its subdirectories (local plans and specs, never committed). The Java types also ignore Maven `target/` output and Eclipse files. To ignore more, call the inherited `addGitIgnore()` method after constructing the project in your `.projenrc.ts`:\n\n```typescript\n// .projenrc.ts\nimport { CdkInfraProject } from '@xpertss/projen-types';\n\nconst project = new CdkInfraProject({\n name: 'my-infra',\n});\n\nproject.addGitIgnore('*.log');\nproject.addGitIgnore('.env.*');\nproject.addGitIgnore('/build/');\n\nproject.synth();\n```\n\nThe same works for every type - just swap the class (e.g. `JavaServiceProject`, `GitHubActionProject`). Each call takes one standard gitignore glob pattern. There is no `gitignore` constructor option: the project types' option interfaces do not expose one, so patterns go through `addGitIgnore()` instead.\n\nRe-run `npx projen` after editing - `.gitignore` is a generated file, so hand-editing it is caught by the drift check.\n\n## Troubleshooting\n\n**`Unable to find projen project. Use \"projen new\" to create a new project.`**\nIf the directory already has a `.projenrc.ts`, this error means the rc has\nnever been synthesized (there's no `.projen/tasks.json`), not that you need a\nnew project. See [Starting from an existing `.projenrc.ts`](#starting-from-an-existing-projenrcts).\n\n## Going further\n\nThe project types are composed from smaller components you can also attach to your own projects:\n\n| Component | Applies to | Purpose |\n| --- | --- | --- |\n| `AppRuntimeScaffold` | `NodeProject` | App source skeleton (`app.ts` + handlers) |\n| `DatabaseComponent` | `NodeProject` | Database construct stub + migration tool wiring |\n| `EcrEcsConstructs` | `Project` | ECR + Fargate ECS construct helper |\n| `EdgeNetworkingConstructs` | `Project` | Per-resource edge networking construct helpers |\n| `MavenPom` | `Project` | A `pom.xml` with modules, BOM imports, dependency/plugin management, and exact versions only |\n| `MavenModule` | `JavaMavenProject` | One module of a reactor (created by `addModule()`) |\n| `MavenUpgradeReport` | `GitHubProject` | Nightly report-only `upgrade.yml` |\n| `MavenCentralPublish` | `JavaMavenProject` | Manual-dispatch Maven Central publish workflow |\n| `DockerPublish` | `JavaMavenProject` | Manual-dispatch Docker build+push workflow |\n| `GitHubPackagesPublish` | `JavaMavenProject` | Manual-dispatch GitHub Packages publish workflow |\n| `FlywayMigration` | `JavaSpringBootProject` | Flyway plugin/dependency + migrations directory |\n| `CdkDeployHook` | `JavaMavenProject` | Manual-dispatch workflow that triggers `deploy.yml` in a companion CDK repo |\n| `CodeIndexWorkflow` | `JavaMavenProject` | Code index generation on push to `main` |\n| `ActionBuildWorkflow` | `GitHubProject` | The `lint` task (shellcheck/yamllint/pinned actionlint) + `build.yml` |\n| `ActionDogfoodWorkflow` | `GitHubProject` | `test-dogfood.yml` from an `ActionDogfoodOptions` scenario |\n| `SonarWorkflow` | `GitHubProject` | `sonar.yml` (SonarCloud scan via the Scanner CLI); opt-in, shared by every type via `sonarHostUrl` |\n\nExample - adding a Docker publish to a `JavaMavenProject` (`JavaServiceProject` is the packaged version of this, with Spring Boot):\n\n```typescript\nimport { DockerPublish, JavaMavenProject } from '@xpertss/projen-types';\n\nconst project = new JavaMavenProject({\n name: 'my-service',\n groupId: 'org.xpertss',\n artifactId: 'my-service',\n});\n\nnew DockerPublish(project, { dockerRegistry: 'ghcr.io' });\n\nproject.synth();\n```\n\nThe full API reference, including every option and property, is in [API.md](./API.md).\n"
110
110
  },
111
111
  "repository": {
112
112
  "type": "git",
@@ -422,20 +422,19 @@
422
422
  },
423
423
  "@xpertss/projen-types.ActionSonarWorkflow": {
424
424
  "assembly": "@xpertss/projen-types",
425
- "base": "projen.Component",
425
+ "base": "@xpertss/projen-types.SonarWorkflow",
426
426
  "docs": {
427
- "remarks": "`sonar.inclusions` is set explicitly since default\ninclusions may skip `action.yml` outside `.github/`.",
428
- "stability": "experimental",
429
- "summary": "AD-001 Layer 2: SonarCloud via the Scanner CLI only (never `SonarSource/sonarqube-scan-action` - third-party, and it carried a security advisory)."
427
+ "deprecated": "Renamed to `SonarWorkflow` (now in `src/common/` and applied to\nevery project type, not just actions). Use `SonarWorkflow` instead; this\nsubclass is kept only so existing imports of `ActionSonarWorkflow` keep\ncompiling. It behaves identically to `SonarWorkflow`.",
428
+ "stability": "deprecated"
430
429
  },
431
430
  "fqn": "@xpertss/projen-types.ActionSonarWorkflow",
432
431
  "initializer": {
433
432
  "docs": {
434
- "stability": "experimental"
433
+ "stability": "deprecated"
435
434
  },
436
435
  "locationInModule": {
437
436
  "filename": "src/actions/action-sonar-workflow.ts",
438
- "line": 44
437
+ "line": 11
439
438
  },
440
439
  "parameters": [
441
440
  {
@@ -447,7 +446,7 @@
447
446
  {
448
447
  "name": "options",
449
448
  "type": {
450
- "fqn": "@xpertss/projen-types.ActionSonarWorkflowOptions"
449
+ "fqn": "@xpertss/projen-types.SonarWorkflowOptions"
451
450
  }
452
451
  }
453
452
  ]
@@ -455,113 +454,11 @@
455
454
  "kind": "class",
456
455
  "locationInModule": {
457
456
  "filename": "src/actions/action-sonar-workflow.ts",
458
- "line": 41
457
+ "line": 10
459
458
  },
460
459
  "name": "ActionSonarWorkflow",
461
- "properties": [
462
- {
463
- "docs": {
464
- "stability": "experimental"
465
- },
466
- "immutable": true,
467
- "locationInModule": {
468
- "filename": "src/actions/action-sonar-workflow.ts",
469
- "line": 42
470
- },
471
- "name": "workflow",
472
- "type": {
473
- "fqn": "projen.github.GithubWorkflow"
474
- }
475
- }
476
- ],
477
460
  "symbolId": "src/actions/action-sonar-workflow:ActionSonarWorkflow"
478
461
  },
479
- "@xpertss/projen-types.ActionSonarWorkflowOptions": {
480
- "assembly": "@xpertss/projen-types",
481
- "datatype": true,
482
- "docs": {
483
- "stability": "experimental"
484
- },
485
- "fqn": "@xpertss/projen-types.ActionSonarWorkflowOptions",
486
- "kind": "interface",
487
- "locationInModule": {
488
- "filename": "src/actions/action-sonar-workflow.ts",
489
- "line": 10
490
- },
491
- "name": "ActionSonarWorkflowOptions",
492
- "properties": [
493
- {
494
- "abstract": true,
495
- "docs": {
496
- "stability": "experimental",
497
- "summary": "URL of the org's SonarCloud instance (e.g. `https://sonarcloud.io`). Required, no default - a guessed server is worse than a loud failure."
498
- },
499
- "immutable": true,
500
- "locationInModule": {
501
- "filename": "src/actions/action-sonar-workflow.ts",
502
- "line": 15
503
- },
504
- "name": "sonarHostUrl",
505
- "type": {
506
- "primitive": "string"
507
- }
508
- },
509
- {
510
- "abstract": true,
511
- "docs": {
512
- "default": "\"xpertss\"",
513
- "stability": "experimental",
514
- "summary": "SonarCloud organization key (`sonar.organization`). Mandatory for the Scanner CLI on SonarCloud - it is not derived from the token, so a scan without it always fails."
515
- },
516
- "immutable": true,
517
- "locationInModule": {
518
- "filename": "src/actions/action-sonar-workflow.ts",
519
- "line": 23
520
- },
521
- "name": "sonarOrganization",
522
- "optional": true,
523
- "type": {
524
- "primitive": "string"
525
- }
526
- },
527
- {
528
- "abstract": true,
529
- "docs": {
530
- "default": "true",
531
- "stability": "experimental",
532
- "summary": "Whether `sonar.yml` also runs on `pull_request` as a pass/fail gate."
533
- },
534
- "immutable": true,
535
- "locationInModule": {
536
- "filename": "src/actions/action-sonar-workflow.ts",
537
- "line": 32
538
- },
539
- "name": "sonarPullRequestGate",
540
- "optional": true,
541
- "type": {
542
- "primitive": "boolean"
543
- }
544
- },
545
- {
546
- "abstract": true,
547
- "docs": {
548
- "default": "\"SONAR_TOKEN\"",
549
- "stability": "experimental"
550
- },
551
- "immutable": true,
552
- "locationInModule": {
553
- "filename": "src/actions/action-sonar-workflow.ts",
554
- "line": 26
555
- },
556
- "name": "sonarTokenSecret",
557
- "optional": true,
558
- "type": {
559
- "primitive": "string"
560
- }
561
- }
562
- ],
563
- "symbolId": "src/actions/action-sonar-workflow:ActionSonarWorkflowOptions"
564
- },
565
462
  "@xpertss/projen-types.AppRuntimeScaffold": {
566
463
  "assembly": "@xpertss/projen-types",
567
464
  "base": "projen.Component",
@@ -648,7 +545,7 @@
648
545
  "kind": "interface",
649
546
  "locationInModule": {
650
547
  "filename": "src/cdk/options.ts",
651
- "line": 92
548
+ "line": 93
652
549
  },
653
550
  "name": "CdkAppProjectOptions",
654
551
  "properties": [
@@ -661,7 +558,7 @@
661
558
  "immutable": true,
662
559
  "locationInModule": {
663
560
  "filename": "src/cdk/options.ts",
664
- "line": 96
561
+ "line": 97
665
562
  },
666
563
  "name": "appEntryPoint",
667
564
  "optional": true,
@@ -677,7 +574,7 @@
677
574
  "immutable": true,
678
575
  "locationInModule": {
679
576
  "filename": "src/cdk/options.ts",
680
- "line": 93
577
+ "line": 94
681
578
  },
682
579
  "name": "database",
683
580
  "optional": true,
@@ -759,7 +656,7 @@
759
656
  "kind": "interface",
760
657
  "locationInModule": {
761
658
  "filename": "src/java/options.ts",
762
- "line": 152
659
+ "line": 150
763
660
  },
764
661
  "name": "CdkDeployHookOptions",
765
662
  "properties": [
@@ -773,7 +670,7 @@
773
670
  "immutable": true,
774
671
  "locationInModule": {
775
672
  "filename": "src/java/options.ts",
776
- "line": 160
673
+ "line": 158
777
674
  },
778
675
  "name": "targetRepo",
779
676
  "optional": true,
@@ -831,7 +728,7 @@
831
728
  "kind": "interface",
832
729
  "locationInModule": {
833
730
  "filename": "src/cdk/options.ts",
834
- "line": 63
731
+ "line": 64
835
732
  },
836
733
  "name": "CdkInfraProjectOptions",
837
734
  "properties": [
@@ -843,7 +740,7 @@
843
740
  "immutable": true,
844
741
  "locationInModule": {
845
742
  "filename": "src/cdk/options.ts",
846
- "line": 79
743
+ "line": 80
847
744
  },
848
745
  "name": "ecrEcs",
849
746
  "optional": true,
@@ -859,7 +756,7 @@
859
756
  "immutable": true,
860
757
  "locationInModule": {
861
758
  "filename": "src/cdk/options.ts",
862
- "line": 81
759
+ "line": 82
863
760
  },
864
761
  "name": "edgeResources",
865
762
  "optional": true,
@@ -883,7 +780,7 @@
883
780
  "immutable": true,
884
781
  "locationInModule": {
885
782
  "filename": "src/cdk/options.ts",
886
- "line": 77
783
+ "line": 78
887
784
  },
888
785
  "name": "environments",
889
786
  "optional": true,
@@ -922,7 +819,7 @@
922
819
  },
923
820
  "locationInModule": {
924
821
  "filename": "src/cdk/cdk-typescript-base.ts",
925
- "line": 31
822
+ "line": 35
926
823
  },
927
824
  "parameters": [
928
825
  {
@@ -936,9 +833,27 @@
936
833
  "kind": "class",
937
834
  "locationInModule": {
938
835
  "filename": "src/cdk/cdk-typescript-base.ts",
939
- "line": 30
836
+ "line": 31
940
837
  },
941
838
  "name": "CdkTypescriptProject",
839
+ "properties": [
840
+ {
841
+ "docs": {
842
+ "stability": "experimental",
843
+ "summary": "Set only when `sonarHostUrl` is provided."
844
+ },
845
+ "immutable": true,
846
+ "locationInModule": {
847
+ "filename": "src/cdk/cdk-typescript-base.ts",
848
+ "line": 33
849
+ },
850
+ "name": "sonarWorkflow",
851
+ "optional": true,
852
+ "type": {
853
+ "fqn": "@xpertss/projen-types.SonarWorkflow"
854
+ }
855
+ }
856
+ ],
942
857
  "symbolId": "src/cdk/cdk-typescript-base:CdkTypescriptProject"
943
858
  },
944
859
  "@xpertss/projen-types.CdkTypescriptProjectOptions": {
@@ -954,7 +869,7 @@
954
869
  "kind": "interface",
955
870
  "locationInModule": {
956
871
  "filename": "src/cdk/cdk-typescript-base.ts",
957
- "line": 19
872
+ "line": 20
958
873
  },
959
874
  "name": "CdkTypescriptProjectOptions",
960
875
  "properties": [
@@ -966,7 +881,7 @@
966
881
  "immutable": true,
967
882
  "locationInModule": {
968
883
  "filename": "src/cdk/cdk-typescript-base.ts",
969
- "line": 20
884
+ "line": 21
970
885
  },
971
886
  "name": "environments",
972
887
  "optional": true,
@@ -1031,10 +946,13 @@
1031
946
  "stability": "experimental"
1032
947
  },
1033
948
  "fqn": "@xpertss/projen-types.CommonCdkOptions",
949
+ "interfaces": [
950
+ "@xpertss/projen-types.SonarScanOptions"
951
+ ],
1034
952
  "kind": "interface",
1035
953
  "locationInModule": {
1036
954
  "filename": "src/cdk/options.ts",
1037
- "line": 23
955
+ "line": 24
1038
956
  },
1039
957
  "name": "CommonCdkOptions",
1040
958
  "properties": [
@@ -1046,7 +964,7 @@
1046
964
  "immutable": true,
1047
965
  "locationInModule": {
1048
966
  "filename": "src/cdk/options.ts",
1049
- "line": 24
967
+ "line": 25
1050
968
  },
1051
969
  "name": "name",
1052
970
  "type": {
@@ -1062,7 +980,7 @@
1062
980
  "immutable": true,
1063
981
  "locationInModule": {
1064
982
  "filename": "src/cdk/options.ts",
1065
- "line": 27
983
+ "line": 28
1066
984
  },
1067
985
  "name": "cdkVersion",
1068
986
  "optional": true,
@@ -1080,7 +998,7 @@
1080
998
  "immutable": true,
1081
999
  "locationInModule": {
1082
1000
  "filename": "src/cdk/options.ts",
1083
- "line": 48
1001
+ "line": 49
1084
1002
  },
1085
1003
  "name": "copyrightOwner",
1086
1004
  "optional": true,
@@ -1098,7 +1016,7 @@
1098
1016
  "immutable": true,
1099
1017
  "locationInModule": {
1100
1018
  "filename": "src/cdk/options.ts",
1101
- "line": 54
1019
+ "line": 55
1102
1020
  },
1103
1021
  "name": "copyrightPeriod",
1104
1022
  "optional": true,
@@ -1116,7 +1034,7 @@
1116
1034
  "immutable": true,
1117
1035
  "locationInModule": {
1118
1036
  "filename": "src/cdk/options.ts",
1119
- "line": 60
1037
+ "line": 61
1120
1038
  },
1121
1039
  "name": "editorconfig",
1122
1040
  "optional": true,
@@ -1133,7 +1051,7 @@
1133
1051
  "immutable": true,
1134
1052
  "locationInModule": {
1135
1053
  "filename": "src/cdk/options.ts",
1136
- "line": 30
1054
+ "line": 31
1137
1055
  },
1138
1056
  "name": "gheTokenSecret",
1139
1057
  "optional": true,
@@ -1151,7 +1069,7 @@
1151
1069
  "immutable": true,
1152
1070
  "locationInModule": {
1153
1071
  "filename": "src/cdk/options.ts",
1154
- "line": 42
1072
+ "line": 43
1155
1073
  },
1156
1074
  "name": "license",
1157
1075
  "optional": true,
@@ -1169,7 +1087,7 @@
1169
1087
  "immutable": true,
1170
1088
  "locationInModule": {
1171
1089
  "filename": "src/cdk/options.ts",
1172
- "line": 36
1090
+ "line": 37
1173
1091
  },
1174
1092
  "name": "licensed",
1175
1093
  "optional": true,
@@ -1187,10 +1105,13 @@
1187
1105
  "stability": "experimental"
1188
1106
  },
1189
1107
  "fqn": "@xpertss/projen-types.CommonJavaOptions",
1108
+ "interfaces": [
1109
+ "@xpertss/projen-types.SonarScanOptions"
1110
+ ],
1190
1111
  "kind": "interface",
1191
1112
  "locationInModule": {
1192
1113
  "filename": "src/java/options.ts",
1193
- "line": 3
1114
+ "line": 4
1194
1115
  },
1195
1116
  "name": "CommonJavaOptions",
1196
1117
  "properties": [
@@ -1202,7 +1123,7 @@
1202
1123
  "immutable": true,
1203
1124
  "locationInModule": {
1204
1125
  "filename": "src/java/options.ts",
1205
- "line": 6
1126
+ "line": 7
1206
1127
  },
1207
1128
  "name": "artifactId",
1208
1129
  "type": {
@@ -1217,7 +1138,7 @@
1217
1138
  "immutable": true,
1218
1139
  "locationInModule": {
1219
1140
  "filename": "src/java/options.ts",
1220
- "line": 5
1141
+ "line": 6
1221
1142
  },
1222
1143
  "name": "groupId",
1223
1144
  "type": {
@@ -1232,7 +1153,7 @@
1232
1153
  "immutable": true,
1233
1154
  "locationInModule": {
1234
1155
  "filename": "src/java/options.ts",
1235
- "line": 4
1156
+ "line": 5
1236
1157
  },
1237
1158
  "name": "name",
1238
1159
  "type": {
@@ -1249,7 +1170,7 @@
1249
1170
  "immutable": true,
1250
1171
  "locationInModule": {
1251
1172
  "filename": "src/java/options.ts",
1252
- "line": 103
1173
+ "line": 101
1253
1174
  },
1254
1175
  "name": "copyrightOwner",
1255
1176
  "optional": true,
@@ -1267,7 +1188,7 @@
1267
1188
  "immutable": true,
1268
1189
  "locationInModule": {
1269
1190
  "filename": "src/java/options.ts",
1270
- "line": 109
1191
+ "line": 107
1271
1192
  },
1272
1193
  "name": "copyrightPeriod",
1273
1194
  "optional": true,
@@ -1285,7 +1206,7 @@
1285
1206
  "immutable": true,
1286
1207
  "locationInModule": {
1287
1208
  "filename": "src/java/options.ts",
1288
- "line": 12
1209
+ "line": 13
1289
1210
  },
1290
1211
  "name": "description",
1291
1212
  "optional": true,
@@ -1303,7 +1224,7 @@
1303
1224
  "immutable": true,
1304
1225
  "locationInModule": {
1305
1226
  "filename": "src/java/options.ts",
1306
- "line": 115
1227
+ "line": 113
1307
1228
  },
1308
1229
  "name": "editorconfig",
1309
1230
  "optional": true,
@@ -1322,7 +1243,7 @@
1322
1243
  "immutable": true,
1323
1244
  "locationInModule": {
1324
1245
  "filename": "src/java/options.ts",
1325
- "line": 67
1246
+ "line": 65
1326
1247
  },
1327
1248
  "name": "enforcer",
1328
1249
  "optional": true,
@@ -1339,7 +1260,7 @@
1339
1260
  "immutable": true,
1340
1261
  "locationInModule": {
1341
1262
  "filename": "src/java/options.ts",
1342
- "line": 21
1263
+ "line": 19
1343
1264
  },
1344
1265
  "name": "gheTokenSecret",
1345
1266
  "optional": true,
@@ -1357,7 +1278,7 @@
1357
1278
  "immutable": true,
1358
1279
  "locationInModule": {
1359
1280
  "filename": "src/java/options.ts",
1360
- "line": 40
1281
+ "line": 38
1361
1282
  },
1362
1283
  "name": "javaDistribution",
1363
1284
  "optional": true,
@@ -1376,7 +1297,7 @@
1376
1297
  "immutable": true,
1377
1298
  "locationInModule": {
1378
1299
  "filename": "src/java/options.ts",
1379
- "line": 34
1300
+ "line": 32
1380
1301
  },
1381
1302
  "name": "javaVersion",
1382
1303
  "optional": true,
@@ -1394,7 +1315,7 @@
1394
1315
  "immutable": true,
1395
1316
  "locationInModule": {
1396
1317
  "filename": "src/java/options.ts",
1397
- "line": 97
1318
+ "line": 95
1398
1319
  },
1399
1320
  "name": "license",
1400
1321
  "optional": true,
@@ -1412,7 +1333,7 @@
1412
1333
  "immutable": true,
1413
1334
  "locationInModule": {
1414
1335
  "filename": "src/java/options.ts",
1415
- "line": 91
1336
+ "line": 89
1416
1337
  },
1417
1338
  "name": "licensed",
1418
1339
  "optional": true,
@@ -1431,7 +1352,7 @@
1431
1352
  "immutable": true,
1432
1353
  "locationInModule": {
1433
1354
  "filename": "src/java/options.ts",
1434
- "line": 75
1355
+ "line": 73
1435
1356
  },
1436
1357
  "name": "minMavenVersion",
1437
1358
  "optional": true,
@@ -1450,7 +1371,7 @@
1450
1371
  "immutable": true,
1451
1372
  "locationInModule": {
1452
1373
  "filename": "src/java/options.ts",
1453
- "line": 49
1374
+ "line": 47
1454
1375
  },
1455
1376
  "name": "packaging",
1456
1377
  "optional": true,
@@ -1468,7 +1389,7 @@
1468
1389
  "immutable": true,
1469
1390
  "locationInModule": {
1470
1391
  "filename": "src/java/options.ts",
1471
- "line": 85
1392
+ "line": 83
1472
1393
  },
1473
1394
  "name": "pluginVersions",
1474
1395
  "optional": true,
@@ -1492,7 +1413,7 @@
1492
1413
  "immutable": true,
1493
1414
  "locationInModule": {
1494
1415
  "filename": "src/java/options.ts",
1495
- "line": 57
1416
+ "line": 55
1496
1417
  },
1497
1418
  "name": "sample",
1498
1419
  "optional": true,
@@ -1500,24 +1421,6 @@
1500
1421
  "primitive": "boolean"
1501
1422
  }
1502
1423
  },
1503
- {
1504
- "abstract": true,
1505
- "docs": {
1506
- "remarks": "If unset, the sonar scan step is skipped.",
1507
- "stability": "experimental",
1508
- "summary": "SonarCloud project key."
1509
- },
1510
- "immutable": true,
1511
- "locationInModule": {
1512
- "filename": "src/java/options.ts",
1513
- "line": 18
1514
- },
1515
- "name": "sonarProjectKey",
1516
- "optional": true,
1517
- "type": {
1518
- "primitive": "string"
1519
- }
1520
- },
1521
1424
  {
1522
1425
  "abstract": true,
1523
1426
  "docs": {
@@ -1528,7 +1431,7 @@
1528
1431
  "immutable": true,
1529
1432
  "locationInModule": {
1530
1433
  "filename": "src/java/options.ts",
1531
- "line": 124
1434
+ "line": 122
1532
1435
  },
1533
1436
  "name": "upgradeWorkflow",
1534
1437
  "optional": true,
@@ -1546,7 +1449,7 @@
1546
1449
  "immutable": true,
1547
1450
  "locationInModule": {
1548
1451
  "filename": "src/java/options.ts",
1549
- "line": 15
1452
+ "line": 16
1550
1453
  },
1551
1454
  "name": "url",
1552
1455
  "optional": true,
@@ -1563,7 +1466,7 @@
1563
1466
  "immutable": true,
1564
1467
  "locationInModule": {
1565
1468
  "filename": "src/java/options.ts",
1566
- "line": 9
1469
+ "line": 10
1567
1470
  },
1568
1471
  "name": "version",
1569
1472
  "optional": true,
@@ -1625,7 +1528,7 @@
1625
1528
  "kind": "interface",
1626
1529
  "locationInModule": {
1627
1530
  "filename": "src/cdk/options.ts",
1628
- "line": 84
1531
+ "line": 85
1629
1532
  },
1630
1533
  "name": "DatabaseOptions",
1631
1534
  "properties": [
@@ -1638,7 +1541,7 @@
1638
1541
  "immutable": true,
1639
1542
  "locationInModule": {
1640
1543
  "filename": "src/cdk/options.ts",
1641
- "line": 86
1544
+ "line": 87
1642
1545
  },
1643
1546
  "name": "engine",
1644
1547
  "optional": true,
@@ -1655,7 +1558,7 @@
1655
1558
  "immutable": true,
1656
1559
  "locationInModule": {
1657
1560
  "filename": "src/cdk/options.ts",
1658
- "line": 89
1561
+ "line": 90
1659
1562
  },
1660
1563
  "name": "migrationTool",
1661
1564
  "optional": true,
@@ -1791,7 +1694,7 @@
1791
1694
  "kind": "interface",
1792
1695
  "locationInModule": {
1793
1696
  "filename": "src/cdk/options.ts",
1794
- "line": 10
1697
+ "line": 11
1795
1698
  },
1796
1699
  "name": "EcrEcsOptions",
1797
1700
  "properties": [
@@ -1804,7 +1707,7 @@
1804
1707
  "immutable": true,
1805
1708
  "locationInModule": {
1806
1709
  "filename": "src/cdk/options.ts",
1807
- "line": 12
1710
+ "line": 13
1808
1711
  },
1809
1712
  "name": "enabled",
1810
1713
  "optional": true,
@@ -1822,7 +1725,7 @@
1822
1725
  "immutable": true,
1823
1726
  "locationInModule": {
1824
1727
  "filename": "src/cdk/options.ts",
1825
- "line": 20
1728
+ "line": 21
1826
1729
  },
1827
1730
  "name": "externalImageSource",
1828
1731
  "optional": true,
@@ -2011,7 +1914,7 @@
2011
1914
  },
2012
1915
  "locationInModule": {
2013
1916
  "filename": "src/actions/github-action-project.ts",
2014
- "line": 161
1917
+ "line": 141
2015
1918
  },
2016
1919
  "parameters": [
2017
1920
  {
@@ -2025,7 +1928,7 @@
2025
1928
  "kind": "class",
2026
1929
  "locationInModule": {
2027
1930
  "filename": "src/actions/github-action-project.ts",
2028
- "line": 155
1931
+ "line": 134
2029
1932
  },
2030
1933
  "name": "GitHubActionProject",
2031
1934
  "properties": [
@@ -2036,7 +1939,7 @@
2036
1939
  "immutable": true,
2037
1940
  "locationInModule": {
2038
1941
  "filename": "src/actions/github-action-project.ts",
2039
- "line": 156
1942
+ "line": 135
2040
1943
  },
2041
1944
  "name": "buildWorkflow",
2042
1945
  "type": {
@@ -2050,7 +1953,7 @@
2050
1953
  "immutable": true,
2051
1954
  "locationInModule": {
2052
1955
  "filename": "src/actions/github-action-project.ts",
2053
- "line": 157
1956
+ "line": 136
2054
1957
  },
2055
1958
  "name": "dogfoodWorkflow",
2056
1959
  "type": {
@@ -2064,7 +1967,7 @@
2064
1967
  "immutable": true,
2065
1968
  "locationInModule": {
2066
1969
  "filename": "src/actions/github-action-project.ts",
2067
- "line": 159
1970
+ "line": 139
2068
1971
  },
2069
1972
  "name": "release",
2070
1973
  "type": {
@@ -2073,16 +1976,18 @@
2073
1976
  },
2074
1977
  {
2075
1978
  "docs": {
2076
- "stability": "experimental"
1979
+ "stability": "experimental",
1980
+ "summary": "Set only when `sonarHostUrl` is provided."
2077
1981
  },
2078
1982
  "immutable": true,
2079
1983
  "locationInModule": {
2080
1984
  "filename": "src/actions/github-action-project.ts",
2081
- "line": 158
1985
+ "line": 138
2082
1986
  },
2083
1987
  "name": "sonarWorkflow",
1988
+ "optional": true,
2084
1989
  "type": {
2085
- "fqn": "@xpertss/projen-types.ActionSonarWorkflow"
1990
+ "fqn": "@xpertss/projen-types.SonarWorkflow"
2086
1991
  }
2087
1992
  }
2088
1993
  ],
@@ -2096,31 +2001,16 @@
2096
2001
  },
2097
2002
  "fqn": "@xpertss/projen-types.GitHubActionProjectOptions",
2098
2003
  "interfaces": [
2099
- "projen.github.GitHubProjectOptions"
2004
+ "projen.github.GitHubProjectOptions",
2005
+ "@xpertss/projen-types.SonarScanOptions"
2100
2006
  ],
2101
2007
  "kind": "interface",
2102
2008
  "locationInModule": {
2103
2009
  "filename": "src/actions/github-action-project.ts",
2104
- "line": 36
2010
+ "line": 37
2105
2011
  },
2106
2012
  "name": "GitHubActionProjectOptions",
2107
2013
  "properties": [
2108
- {
2109
- "abstract": true,
2110
- "docs": {
2111
- "stability": "experimental",
2112
- "summary": "URL of the org's SonarCloud instance (e.g. `https://sonarcloud.io`). MUST be reachable from github.com-hosted (public) runners (AD-001). Required, no default: a guessed server is worse than a loud failure."
2113
- },
2114
- "immutable": true,
2115
- "locationInModule": {
2116
- "filename": "src/actions/github-action-project.ts",
2117
- "line": 59
2118
- },
2119
- "name": "sonarHostUrl",
2120
- "type": {
2121
- "primitive": "string"
2122
- }
2123
- },
2124
2014
  {
2125
2015
  "abstract": true,
2126
2016
  "docs": {
@@ -2131,7 +2021,7 @@
2131
2021
  "immutable": true,
2132
2022
  "locationInModule": {
2133
2023
  "filename": "src/actions/github-action-project.ts",
2134
- "line": 104
2024
+ "line": 83
2135
2025
  },
2136
2026
  "name": "copyrightOwner",
2137
2027
  "optional": true,
@@ -2149,7 +2039,7 @@
2149
2039
  "immutable": true,
2150
2040
  "locationInModule": {
2151
2041
  "filename": "src/actions/github-action-project.ts",
2152
- "line": 110
2042
+ "line": 89
2153
2043
  },
2154
2044
  "name": "copyrightPeriod",
2155
2045
  "optional": true,
@@ -2167,7 +2057,7 @@
2167
2057
  "immutable": true,
2168
2058
  "locationInModule": {
2169
2059
  "filename": "src/actions/github-action-project.ts",
2170
- "line": 42
2060
+ "line": 44
2171
2061
  },
2172
2062
  "name": "description",
2173
2063
  "optional": true,
@@ -2186,7 +2076,7 @@
2186
2076
  "immutable": true,
2187
2077
  "locationInModule": {
2188
2078
  "filename": "src/actions/github-action-project.ts",
2189
- "line": 92
2079
+ "line": 71
2190
2080
  },
2191
2081
  "name": "dogfood",
2192
2082
  "optional": true,
@@ -2204,7 +2094,7 @@
2204
2094
  "immutable": true,
2205
2095
  "locationInModule": {
2206
2096
  "filename": "src/actions/github-action-project.ts",
2207
- "line": 116
2097
+ "line": 95
2208
2098
  },
2209
2099
  "name": "editorconfig",
2210
2100
  "optional": true,
@@ -2223,7 +2113,7 @@
2223
2113
  "immutable": true,
2224
2114
  "locationInModule": {
2225
2115
  "filename": "src/actions/github-action-project.ts",
2226
- "line": 52
2116
+ "line": 54
2227
2117
  },
2228
2118
  "name": "gheTokenSecret",
2229
2119
  "optional": true,
@@ -2241,66 +2131,13 @@
2241
2131
  "immutable": true,
2242
2132
  "locationInModule": {
2243
2133
  "filename": "src/actions/github-action-project.ts",
2244
- "line": 98
2134
+ "line": 77
2245
2135
  },
2246
2136
  "name": "license",
2247
2137
  "optional": true,
2248
2138
  "type": {
2249
2139
  "primitive": "string"
2250
2140
  }
2251
- },
2252
- {
2253
- "abstract": true,
2254
- "docs": {
2255
- "default": "\"xpertss\"",
2256
- "stability": "experimental",
2257
- "summary": "SonarCloud organization key (`sonar.organization`), required by the Scanner CLI on SonarCloud."
2258
- },
2259
- "immutable": true,
2260
- "locationInModule": {
2261
- "filename": "src/actions/github-action-project.ts",
2262
- "line": 66
2263
- },
2264
- "name": "sonarOrganization",
2265
- "optional": true,
2266
- "type": {
2267
- "primitive": "string"
2268
- }
2269
- },
2270
- {
2271
- "abstract": true,
2272
- "docs": {
2273
- "default": "true",
2274
- "stability": "experimental",
2275
- "summary": "Whether `sonar.yml` also runs on `pull_request` as a pass/fail gate."
2276
- },
2277
- "immutable": true,
2278
- "locationInModule": {
2279
- "filename": "src/actions/github-action-project.ts",
2280
- "line": 75
2281
- },
2282
- "name": "sonarPullRequestGate",
2283
- "optional": true,
2284
- "type": {
2285
- "primitive": "boolean"
2286
- }
2287
- },
2288
- {
2289
- "abstract": true,
2290
- "docs": {
2291
- "default": "\"SONAR_TOKEN\"",
2292
- "stability": "experimental"
2293
- },
2294
- "immutable": true,
2295
- "locationInModule": {
2296
- "filename": "src/actions/github-action-project.ts",
2297
- "line": 69
2298
- },
2299
- "name": "sonarTokenSecret",
2300
- "optional": true,
2301
- "type": {
2302
- "primitive": "string"
2303
- }
2304
2141
  }
2305
2142
  ],
2306
2143
  "symbolId": "src/actions/github-action-project:GitHubActionProjectOptions"
@@ -2426,7 +2263,7 @@
2426
2263
  "kind": "interface",
2427
2264
  "locationInModule": {
2428
2265
  "filename": "src/java/options.ts",
2429
- "line": 201
2266
+ "line": 199
2430
2267
  },
2431
2268
  "name": "JavaAppProjectOptions",
2432
2269
  "properties": [
@@ -2439,7 +2276,7 @@
2439
2276
  "immutable": true,
2440
2277
  "locationInModule": {
2441
2278
  "filename": "src/java/options.ts",
2442
- "line": 203
2279
+ "line": 201
2443
2280
  },
2444
2281
  "name": "ghPackagesRegistry",
2445
2282
  "optional": true,
@@ -2497,7 +2334,7 @@
2497
2334
  "kind": "interface",
2498
2335
  "locationInModule": {
2499
2336
  "filename": "src/java/options.ts",
2500
- "line": 144
2337
+ "line": 142
2501
2338
  },
2502
2339
  "name": "JavaLibraryProjectOptions",
2503
2340
  "properties": [
@@ -2510,7 +2347,7 @@
2510
2347
  "immutable": true,
2511
2348
  "locationInModule": {
2512
2349
  "filename": "src/java/options.ts",
2513
- "line": 146
2350
+ "line": 144
2514
2351
  },
2515
2352
  "name": "mavenCentralOidc",
2516
2353
  "optional": true,
@@ -2527,7 +2364,7 @@
2527
2364
  "immutable": true,
2528
2365
  "locationInModule": {
2529
2366
  "filename": "src/java/options.ts",
2530
- "line": 149
2367
+ "line": 147
2531
2368
  },
2532
2369
  "name": "publishCodeIndex",
2533
2370
  "optional": true,
@@ -2542,7 +2379,7 @@
2542
2379
  "assembly": "@xpertss/projen-types",
2543
2380
  "base": "projen.github.GitHubProject",
2544
2381
  "docs": {
2545
- "remarks": "It is the base of every Java type in this package and is\nusable on its own (`projen new ... java_maven`).\n\n- The pom is written by this package (`MavenPom`), not projen's\n `java.Pom`: exact versions only, BOM imports, `<modules>`,\n `<dependencyManagement>`, `<pluginManagement>`.\n- Everything Java-version-dependent (compiler level, enforcer rule, JUnit\n line, CI JDK) follows `javaVersion`.\n- With no `addModule()` calls the root pom is the artifact. After the\n first `addModule()` it is a `pom`-packaged reactor parent and the\n modules inherit its plugins and test dependencies.\n- `npx projen build` synthesizes, then runs Maven once: `mvn -B verify`\n (unit tests via surefire, `*IT` tests via failsafe).\n- CI: a PR build (with an optional SonarQube scan), the projen drift\n check, and a nightly report-only update check.",
2382
+ "remarks": "It is the base of every Java type in this package and is\nusable on its own (`projen new ... java_maven`).\n\n- The pom is written by this package (`MavenPom`), not projen's\n `java.Pom`: exact versions only, BOM imports, `<modules>`,\n `<dependencyManagement>`, `<pluginManagement>`.\n- Everything Java-version-dependent (compiler level, enforcer rule, JUnit\n line, CI JDK) follows `javaVersion`.\n- With no `addModule()` calls the root pom is the artifact. After the\n first `addModule()` it is a `pom`-packaged reactor parent and the\n modules inherit its plugins and test dependencies.\n- `npx projen build` synthesizes, then runs Maven once: `mvn -B verify`\n (unit tests via surefire, `*IT` tests via failsafe).\n - CI: a PR build, the projen drift check, an optional SonarCloud scan\n (`sonar.yml`, when `sonarHostUrl` is set), and a nightly report-only\n update check.",
2546
2383
  "stability": "experimental",
2547
2384
  "summary": "Baseline Maven project, single- or multi-module, with no framework assumptions."
2548
2385
  },
@@ -2553,7 +2390,7 @@
2553
2390
  },
2554
2391
  "locationInModule": {
2555
2392
  "filename": "src/java/java-maven-base.ts",
2556
- "line": 85
2393
+ "line": 90
2557
2394
  },
2558
2395
  "parameters": [
2559
2396
  {
@@ -2567,7 +2404,7 @@
2567
2404
  "kind": "class",
2568
2405
  "locationInModule": {
2569
2406
  "filename": "src/java/java-maven-base.ts",
2570
- "line": 56
2407
+ "line": 58
2571
2408
  },
2572
2409
  "methods": [
2573
2410
  {
@@ -2577,7 +2414,7 @@
2577
2414
  },
2578
2415
  "locationInModule": {
2579
2416
  "filename": "src/java/java-maven-base.ts",
2580
- "line": 275
2417
+ "line": 280
2581
2418
  },
2582
2419
  "name": "addBom",
2583
2420
  "parameters": [
@@ -2600,7 +2437,7 @@
2600
2437
  },
2601
2438
  "locationInModule": {
2602
2439
  "filename": "src/java/java-maven-base.ts",
2603
- "line": 297
2440
+ "line": 302
2604
2441
  },
2605
2442
  "name": "addDependency",
2606
2443
  "parameters": [
@@ -2622,7 +2459,7 @@
2622
2459
  },
2623
2460
  "locationInModule": {
2624
2461
  "filename": "src/java/java-maven-base.ts",
2625
- "line": 285
2462
+ "line": 290
2626
2463
  },
2627
2464
  "name": "addManagedDependency",
2628
2465
  "parameters": [
@@ -2645,7 +2482,7 @@
2645
2482
  },
2646
2483
  "locationInModule": {
2647
2484
  "filename": "src/java/java-maven-base.ts",
2648
- "line": 244
2485
+ "line": 249
2649
2486
  },
2650
2487
  "name": "addModule",
2651
2488
  "parameters": [
@@ -2669,7 +2506,7 @@
2669
2506
  },
2670
2507
  "locationInModule": {
2671
2508
  "filename": "src/java/java-maven-base.ts",
2672
- "line": 307
2509
+ "line": 312
2673
2510
  },
2674
2511
  "name": "addPlugin",
2675
2512
  "parameters": [
@@ -2695,7 +2532,7 @@
2695
2532
  },
2696
2533
  "locationInModule": {
2697
2534
  "filename": "src/java/java-maven-base.ts",
2698
- "line": 302
2535
+ "line": 307
2699
2536
  },
2700
2537
  "name": "addTestDependency",
2701
2538
  "parameters": [
@@ -2714,7 +2551,7 @@
2714
2551
  },
2715
2552
  "locationInModule": {
2716
2553
  "filename": "src/java/java-maven-base.ts",
2717
- "line": 335
2554
+ "line": 340
2718
2555
  },
2719
2556
  "name": "maxSpringBootMajor",
2720
2557
  "protected": true,
@@ -2732,7 +2569,7 @@
2732
2569
  },
2733
2570
  "locationInModule": {
2734
2571
  "filename": "src/java/java-maven-base.ts",
2735
- "line": 323
2572
+ "line": 328
2736
2573
  },
2737
2574
  "name": "pinnedVersion",
2738
2575
  "parameters": [
@@ -2756,7 +2593,7 @@
2756
2593
  },
2757
2594
  "locationInModule": {
2758
2595
  "filename": "src/java/java-maven-base.ts",
2759
- "line": 311
2596
+ "line": 316
2760
2597
  },
2761
2598
  "name": "preSynthesize",
2762
2599
  "overrides": "projen.Project"
@@ -2772,7 +2609,7 @@
2772
2609
  "immutable": true,
2773
2610
  "locationInModule": {
2774
2611
  "filename": "src/java/java-maven-base.ts",
2775
- "line": 71
2612
+ "line": 73
2776
2613
  },
2777
2614
  "name": "buildVerifyWorkflow",
2778
2615
  "type": {
@@ -2787,7 +2624,7 @@
2787
2624
  "immutable": true,
2788
2625
  "locationInModule": {
2789
2626
  "filename": "src/java/java-maven-base.ts",
2790
- "line": 77
2627
+ "line": 79
2791
2628
  },
2792
2629
  "name": "ciSetupSteps",
2793
2630
  "type": {
@@ -2807,7 +2644,7 @@
2807
2644
  "immutable": true,
2808
2645
  "locationInModule": {
2809
2646
  "filename": "src/java/java-maven-base.ts",
2810
- "line": 61
2647
+ "line": 63
2811
2648
  },
2812
2649
  "name": "javaVersion",
2813
2650
  "type": {
@@ -2822,7 +2659,7 @@
2822
2659
  "immutable": true,
2823
2660
  "locationInModule": {
2824
2661
  "filename": "src/java/java-maven-base.ts",
2825
- "line": 233
2662
+ "line": 238
2826
2663
  },
2827
2664
  "name": "modules",
2828
2665
  "type": {
@@ -2842,26 +2679,42 @@
2842
2679
  "immutable": true,
2843
2680
  "locationInModule": {
2844
2681
  "filename": "src/java/java-maven-base.ts",
2845
- "line": 58
2682
+ "line": 60
2683
+ },
2684
+ "name": "pom",
2685
+ "type": {
2686
+ "fqn": "@xpertss/projen-types.MavenPom"
2687
+ }
2688
+ },
2689
+ {
2690
+ "docs": {
2691
+ "stability": "experimental",
2692
+ "summary": "Prints available dependency/plugin updates (`npx projen upgrade`)."
2693
+ },
2694
+ "immutable": true,
2695
+ "locationInModule": {
2696
+ "filename": "src/java/java-maven-base.ts",
2697
+ "line": 66
2846
2698
  },
2847
- "name": "pom",
2699
+ "name": "upgradeTask",
2848
2700
  "type": {
2849
- "fqn": "@xpertss/projen-types.MavenPom"
2701
+ "fqn": "projen.Task"
2850
2702
  }
2851
2703
  },
2852
2704
  {
2853
2705
  "docs": {
2854
2706
  "stability": "experimental",
2855
- "summary": "Prints available dependency/plugin updates (`npx projen upgrade`)."
2707
+ "summary": "Set only when `sonarHostUrl` is provided."
2856
2708
  },
2857
2709
  "immutable": true,
2858
2710
  "locationInModule": {
2859
2711
  "filename": "src/java/java-maven-base.ts",
2860
- "line": 64
2712
+ "line": 82
2861
2713
  },
2862
- "name": "upgradeTask",
2714
+ "name": "sonarWorkflow",
2715
+ "optional": true,
2863
2716
  "type": {
2864
- "fqn": "projen.Task"
2717
+ "fqn": "@xpertss/projen-types.SonarWorkflow"
2865
2718
  }
2866
2719
  }
2867
2720
  ],
@@ -2881,7 +2734,7 @@
2881
2734
  "kind": "interface",
2882
2735
  "locationInModule": {
2883
2736
  "filename": "src/java/options.ts",
2884
- "line": 128
2737
+ "line": 126
2885
2738
  },
2886
2739
  "name": "JavaMavenProjectOptions",
2887
2740
  "symbolId": "src/java/options:JavaMavenProjectOptions"
@@ -2961,7 +2814,7 @@
2961
2814
  "kind": "interface",
2962
2815
  "locationInModule": {
2963
2816
  "filename": "src/java/options.ts",
2964
- "line": 163
2817
+ "line": 161
2965
2818
  },
2966
2819
  "name": "JavaServiceProjectOptions",
2967
2820
  "properties": [
@@ -2975,7 +2828,7 @@
2975
2828
  "immutable": true,
2976
2829
  "locationInModule": {
2977
2830
  "filename": "src/java/options.ts",
2978
- "line": 190
2831
+ "line": 188
2979
2832
  },
2980
2833
  "name": "cdkDeployHook",
2981
2834
  "optional": true,
@@ -2997,7 +2850,7 @@
2997
2850
  "immutable": true,
2998
2851
  "locationInModule": {
2999
2852
  "filename": "src/java/options.ts",
3000
- "line": 183
2853
+ "line": 181
3001
2854
  },
3002
2855
  "name": "cdkDeployTargetRepo",
3003
2856
  "optional": true,
@@ -3014,7 +2867,7 @@
3014
2867
  "immutable": true,
3015
2868
  "locationInModule": {
3016
2869
  "filename": "src/java/options.ts",
3017
- "line": 165
2870
+ "line": 163
3018
2871
  },
3019
2872
  "name": "dockerRegistry",
3020
2873
  "optional": true,
@@ -3032,7 +2885,7 @@
3032
2885
  "immutable": true,
3033
2886
  "locationInModule": {
3034
2887
  "filename": "src/java/options.ts",
3035
- "line": 198
2888
+ "line": 196
3036
2889
  },
3037
2890
  "name": "environments",
3038
2891
  "optional": true,
@@ -3063,7 +2916,7 @@
3063
2916
  "immutable": true,
3064
2917
  "locationInModule": {
3065
2918
  "filename": "src/java/options.ts",
3066
- "line": 168
2919
+ "line": 166
3067
2920
  },
3068
2921
  "name": "useFlyway",
3069
2922
  "optional": true,
@@ -3177,7 +3030,7 @@
3177
3030
  "kind": "interface",
3178
3031
  "locationInModule": {
3179
3032
  "filename": "src/java/options.ts",
3180
- "line": 131
3033
+ "line": 129
3181
3034
  },
3182
3035
  "name": "JavaSpringBootProjectOptions",
3183
3036
  "properties": [
@@ -3192,7 +3045,7 @@
3192
3045
  "immutable": true,
3193
3046
  "locationInModule": {
3194
3047
  "filename": "src/java/options.ts",
3195
- "line": 141
3048
+ "line": 139
3196
3049
  },
3197
3050
  "name": "springBootVersion",
3198
3051
  "optional": true,
@@ -3547,7 +3400,7 @@
3547
3400
  "kind": "interface",
3548
3401
  "locationInModule": {
3549
3402
  "filename": "src/java/options.ts",
3550
- "line": 207
3403
+ "line": 205
3551
3404
  },
3552
3405
  "name": "MavenModuleOptions",
3553
3406
  "properties": [
@@ -3559,7 +3412,7 @@
3559
3412
  "immutable": true,
3560
3413
  "locationInModule": {
3561
3414
  "filename": "src/java/options.ts",
3562
- "line": 214
3415
+ "line": 212
3563
3416
  },
3564
3417
  "name": "artifactId",
3565
3418
  "type": {
@@ -3575,7 +3428,7 @@
3575
3428
  "immutable": true,
3576
3429
  "locationInModule": {
3577
3430
  "filename": "src/java/options.ts",
3578
- "line": 212
3431
+ "line": 210
3579
3432
  },
3580
3433
  "name": "dir",
3581
3434
  "type": {
@@ -3591,7 +3444,7 @@
3591
3444
  "immutable": true,
3592
3445
  "locationInModule": {
3593
3446
  "filename": "src/java/options.ts",
3594
- "line": 220
3447
+ "line": 218
3595
3448
  },
3596
3449
  "name": "description",
3597
3450
  "optional": true,
@@ -3608,7 +3461,7 @@
3608
3461
  "immutable": true,
3609
3462
  "locationInModule": {
3610
3463
  "filename": "src/java/options.ts",
3611
- "line": 217
3464
+ "line": 215
3612
3465
  },
3613
3466
  "name": "name",
3614
3467
  "optional": true,
@@ -3625,7 +3478,7 @@
3625
3478
  "immutable": true,
3626
3479
  "locationInModule": {
3627
3480
  "filename": "src/java/options.ts",
3628
- "line": 223
3481
+ "line": 221
3629
3482
  },
3630
3483
  "name": "packaging",
3631
3484
  "optional": true,
@@ -4515,6 +4368,289 @@
4515
4368
  ],
4516
4369
  "symbolId": "src/common/projen-drift-check-workflow:ProjenDriftCheckWorkflowOptions"
4517
4370
  },
4371
+ "@xpertss/projen-types.SonarScanOptions": {
4372
+ "assembly": "@xpertss/projen-types",
4373
+ "datatype": true,
4374
+ "docs": {
4375
+ "stability": "experimental"
4376
+ },
4377
+ "fqn": "@xpertss/projen-types.SonarScanOptions",
4378
+ "kind": "interface",
4379
+ "locationInModule": {
4380
+ "filename": "src/common/sonar-options.ts",
4381
+ "line": 1
4382
+ },
4383
+ "name": "SonarScanOptions",
4384
+ "properties": [
4385
+ {
4386
+ "abstract": true,
4387
+ "docs": {
4388
+ "stability": "experimental",
4389
+ "summary": "URL of the org's SonarCloud instance (e.g. `https://sonarcloud.io`). When set, a `sonar.yml` SonarScanner workflow is generated; when omitted, no Sonar workflow is produced. Must be reachable from github.com-hosted (public) runners (AD-001)."
4390
+ },
4391
+ "immutable": true,
4392
+ "locationInModule": {
4393
+ "filename": "src/common/sonar-options.ts",
4394
+ "line": 8
4395
+ },
4396
+ "name": "sonarHostUrl",
4397
+ "optional": true,
4398
+ "type": {
4399
+ "primitive": "string"
4400
+ }
4401
+ },
4402
+ {
4403
+ "abstract": true,
4404
+ "docs": {
4405
+ "default": "\"xpertss\"",
4406
+ "stability": "experimental",
4407
+ "summary": "SonarCloud organization key (`sonar.organization`). Mandatory for the Scanner CLI on SonarCloud - it is not derived from the token, so a scan without it always fails."
4408
+ },
4409
+ "immutable": true,
4410
+ "locationInModule": {
4411
+ "filename": "src/common/sonar-options.ts",
4412
+ "line": 16
4413
+ },
4414
+ "name": "sonarOrganization",
4415
+ "optional": true,
4416
+ "type": {
4417
+ "primitive": "string"
4418
+ }
4419
+ },
4420
+ {
4421
+ "abstract": true,
4422
+ "docs": {
4423
+ "default": "- `${sonarOrganization}_${name}` (the org + project key SonarCloud\nuses, e.g. `xpertss_create-pull-request`)",
4424
+ "stability": "experimental",
4425
+ "summary": "`sonar.projectKey`."
4426
+ },
4427
+ "immutable": true,
4428
+ "locationInModule": {
4429
+ "filename": "src/common/sonar-options.ts",
4430
+ "line": 32
4431
+ },
4432
+ "name": "sonarProjectKey",
4433
+ "optional": true,
4434
+ "type": {
4435
+ "primitive": "string"
4436
+ }
4437
+ },
4438
+ {
4439
+ "abstract": true,
4440
+ "docs": {
4441
+ "default": "true",
4442
+ "stability": "experimental",
4443
+ "summary": "Whether `sonar.yml` also runs on `pull_request` as a pass/fail gate."
4444
+ },
4445
+ "immutable": true,
4446
+ "locationInModule": {
4447
+ "filename": "src/common/sonar-options.ts",
4448
+ "line": 25
4449
+ },
4450
+ "name": "sonarPullRequestGate",
4451
+ "optional": true,
4452
+ "type": {
4453
+ "primitive": "boolean"
4454
+ }
4455
+ },
4456
+ {
4457
+ "abstract": true,
4458
+ "docs": {
4459
+ "default": "\"SONAR_TOKEN\"",
4460
+ "stability": "experimental"
4461
+ },
4462
+ "immutable": true,
4463
+ "locationInModule": {
4464
+ "filename": "src/common/sonar-options.ts",
4465
+ "line": 19
4466
+ },
4467
+ "name": "sonarTokenSecret",
4468
+ "optional": true,
4469
+ "type": {
4470
+ "primitive": "string"
4471
+ }
4472
+ }
4473
+ ],
4474
+ "symbolId": "src/common/sonar-options:SonarScanOptions"
4475
+ },
4476
+ "@xpertss/projen-types.SonarWorkflow": {
4477
+ "assembly": "@xpertss/projen-types",
4478
+ "base": "projen.Component",
4479
+ "docs": {
4480
+ "remarks": "`sonar.projectKey` defaults to\n`${sonarOrganization}_${name}` (the org + project key SonarCloud uses);\n`sonar.inclusions` is emitted only when provided, since the defaults are\nenough for default-recognized languages.",
4481
+ "stability": "experimental",
4482
+ "summary": "AD-001 Layer 2: SonarCloud via the Scanner CLI only (never `SonarSource/sonarqube-scan-action` - third-party, and it carried a security advisory)."
4483
+ },
4484
+ "fqn": "@xpertss/projen-types.SonarWorkflow",
4485
+ "initializer": {
4486
+ "docs": {
4487
+ "stability": "experimental"
4488
+ },
4489
+ "locationInModule": {
4490
+ "filename": "src/common/sonar-workflow.ts",
4491
+ "line": 62
4492
+ },
4493
+ "parameters": [
4494
+ {
4495
+ "name": "scope",
4496
+ "type": {
4497
+ "fqn": "projen.github.GitHubProject"
4498
+ }
4499
+ },
4500
+ {
4501
+ "name": "options",
4502
+ "type": {
4503
+ "fqn": "@xpertss/projen-types.SonarWorkflowOptions"
4504
+ }
4505
+ }
4506
+ ]
4507
+ },
4508
+ "kind": "class",
4509
+ "locationInModule": {
4510
+ "filename": "src/common/sonar-workflow.ts",
4511
+ "line": 59
4512
+ },
4513
+ "name": "SonarWorkflow",
4514
+ "properties": [
4515
+ {
4516
+ "docs": {
4517
+ "stability": "experimental"
4518
+ },
4519
+ "immutable": true,
4520
+ "locationInModule": {
4521
+ "filename": "src/common/sonar-workflow.ts",
4522
+ "line": 60
4523
+ },
4524
+ "name": "workflow",
4525
+ "type": {
4526
+ "fqn": "projen.github.GithubWorkflow"
4527
+ }
4528
+ }
4529
+ ],
4530
+ "symbolId": "src/common/sonar-workflow:SonarWorkflow"
4531
+ },
4532
+ "@xpertss/projen-types.SonarWorkflowOptions": {
4533
+ "assembly": "@xpertss/projen-types",
4534
+ "datatype": true,
4535
+ "docs": {
4536
+ "stability": "experimental"
4537
+ },
4538
+ "fqn": "@xpertss/projen-types.SonarWorkflowOptions",
4539
+ "kind": "interface",
4540
+ "locationInModule": {
4541
+ "filename": "src/common/sonar-workflow.ts",
4542
+ "line": 10
4543
+ },
4544
+ "name": "SonarWorkflowOptions",
4545
+ "properties": [
4546
+ {
4547
+ "abstract": true,
4548
+ "docs": {
4549
+ "stability": "experimental",
4550
+ "summary": "URL of the org's SonarCloud instance (e.g. `https://sonarcloud.io`). Required, no default - a guessed server is worse than a loud failure."
4551
+ },
4552
+ "immutable": true,
4553
+ "locationInModule": {
4554
+ "filename": "src/common/sonar-workflow.ts",
4555
+ "line": 15
4556
+ },
4557
+ "name": "sonarHostUrl",
4558
+ "type": {
4559
+ "primitive": "string"
4560
+ }
4561
+ },
4562
+ {
4563
+ "abstract": true,
4564
+ "docs": {
4565
+ "default": "- none (Sonar's default inclusions)",
4566
+ "stability": "experimental",
4567
+ "summary": "`sonar.inclusions` glob, only needed for files Sonar's default inclusions skip - e.g. a composite action's `action.yml` and `*.sh` scripts, which live outside the defaults. Omit it for default-recognized languages (Java, TypeScript, ...)."
4568
+ },
4569
+ "immutable": true,
4570
+ "locationInModule": {
4571
+ "filename": "src/common/sonar-workflow.ts",
4572
+ "line": 48
4573
+ },
4574
+ "name": "sonarInclusions",
4575
+ "optional": true,
4576
+ "type": {
4577
+ "primitive": "string"
4578
+ }
4579
+ },
4580
+ {
4581
+ "abstract": true,
4582
+ "docs": {
4583
+ "default": "\"xpertss\"",
4584
+ "stability": "experimental",
4585
+ "summary": "SonarCloud organization key (`sonar.organization`). Mandatory for the Scanner CLI on SonarCloud - it is not derived from the token, so a scan without it always fails."
4586
+ },
4587
+ "immutable": true,
4588
+ "locationInModule": {
4589
+ "filename": "src/common/sonar-workflow.ts",
4590
+ "line": 23
4591
+ },
4592
+ "name": "sonarOrganization",
4593
+ "optional": true,
4594
+ "type": {
4595
+ "primitive": "string"
4596
+ }
4597
+ },
4598
+ {
4599
+ "abstract": true,
4600
+ "docs": {
4601
+ "default": "- `${sonarOrganization}_${name}` (the org + project key SonarCloud\nuses, e.g. `xpertss_create-pull-request`)",
4602
+ "stability": "experimental",
4603
+ "summary": "`sonar.projectKey`."
4604
+ },
4605
+ "immutable": true,
4606
+ "locationInModule": {
4607
+ "filename": "src/common/sonar-workflow.ts",
4608
+ "line": 39
4609
+ },
4610
+ "name": "sonarProjectKey",
4611
+ "optional": true,
4612
+ "type": {
4613
+ "primitive": "string"
4614
+ }
4615
+ },
4616
+ {
4617
+ "abstract": true,
4618
+ "docs": {
4619
+ "default": "true",
4620
+ "stability": "experimental",
4621
+ "summary": "Whether `sonar.yml` also runs on `pull_request` as a pass/fail gate."
4622
+ },
4623
+ "immutable": true,
4624
+ "locationInModule": {
4625
+ "filename": "src/common/sonar-workflow.ts",
4626
+ "line": 32
4627
+ },
4628
+ "name": "sonarPullRequestGate",
4629
+ "optional": true,
4630
+ "type": {
4631
+ "primitive": "boolean"
4632
+ }
4633
+ },
4634
+ {
4635
+ "abstract": true,
4636
+ "docs": {
4637
+ "default": "\"SONAR_TOKEN\"",
4638
+ "stability": "experimental"
4639
+ },
4640
+ "immutable": true,
4641
+ "locationInModule": {
4642
+ "filename": "src/common/sonar-workflow.ts",
4643
+ "line": 26
4644
+ },
4645
+ "name": "sonarTokenSecret",
4646
+ "optional": true,
4647
+ "type": {
4648
+ "primitive": "string"
4649
+ }
4650
+ }
4651
+ ],
4652
+ "symbolId": "src/common/sonar-workflow:SonarWorkflowOptions"
4653
+ },
4518
4654
  "@xpertss/projen-types.WorkflowChangeNoticeWorkflow": {
4519
4655
  "assembly": "@xpertss/projen-types",
4520
4656
  "base": "projen.Component",
@@ -4630,6 +4766,6 @@
4630
4766
  "symbolId": "src/common/workflow-change-notice-workflow:WorkflowChangeNoticeWorkflowOptions"
4631
4767
  }
4632
4768
  },
4633
- "version": "0.0.21",
4634
- "fingerprint": "Lpw7m6GjVomXI8FrDCx1XCdRdN23DRQOtGauO0smzeY="
4769
+ "version": "0.0.22",
4770
+ "fingerprint": "X29Pe4ieYhnrNjcCkP20geT95pIeT0dvl9TcMcDDd1A="
4635
4771
  }