@xpertss/projen-types 0.0.20 → 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 +535 -291
  2. package/API.md +1808 -488
  3. package/README.md +46 -17
  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 +15 -22
  9. package/lib/actions/github-action-project.js +18 -13
  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 +25 -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 +22 -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 +19 -15
  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 +3 -4
  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- `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| `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` | `xpertss` / 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| `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": 68
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": 72
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": 69
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": 39
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": 55
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": 57
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": 53
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": 30
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": 29
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": 18
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": 19
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,
@@ -1070,6 +988,42 @@
1070
988
  "primitive": "string"
1071
989
  }
1072
990
  },
991
+ {
992
+ "abstract": true,
993
+ "docs": {
994
+ "default": "\"Xpert Software\"",
995
+ "stability": "experimental",
996
+ "summary": "Copyright owner named in the `LICENSE`."
997
+ },
998
+ "immutable": true,
999
+ "locationInModule": {
1000
+ "filename": "src/cdk/options.ts",
1001
+ "line": 49
1002
+ },
1003
+ "name": "copyrightOwner",
1004
+ "optional": true,
1005
+ "type": {
1006
+ "primitive": "string"
1007
+ }
1008
+ },
1009
+ {
1010
+ "abstract": true,
1011
+ "docs": {
1012
+ "default": "- the current year",
1013
+ "stability": "experimental",
1014
+ "summary": "Copyright period named in the `LICENSE`."
1015
+ },
1016
+ "immutable": true,
1017
+ "locationInModule": {
1018
+ "filename": "src/cdk/options.ts",
1019
+ "line": 55
1020
+ },
1021
+ "name": "copyrightPeriod",
1022
+ "optional": true,
1023
+ "type": {
1024
+ "primitive": "string"
1025
+ }
1026
+ },
1073
1027
  {
1074
1028
  "abstract": true,
1075
1029
  "docs": {
@@ -1080,7 +1034,7 @@
1080
1034
  "immutable": true,
1081
1035
  "locationInModule": {
1082
1036
  "filename": "src/cdk/options.ts",
1083
- "line": 36
1037
+ "line": 61
1084
1038
  },
1085
1039
  "name": "editorconfig",
1086
1040
  "optional": true,
@@ -1097,13 +1051,49 @@
1097
1051
  "immutable": true,
1098
1052
  "locationInModule": {
1099
1053
  "filename": "src/cdk/options.ts",
1100
- "line": 30
1054
+ "line": 31
1101
1055
  },
1102
1056
  "name": "gheTokenSecret",
1103
1057
  "optional": true,
1104
1058
  "type": {
1105
1059
  "primitive": "string"
1106
1060
  }
1061
+ },
1062
+ {
1063
+ "abstract": true,
1064
+ "docs": {
1065
+ "default": "\"MIT\"",
1066
+ "stability": "experimental",
1067
+ "summary": "SPDX identifier for the generated `LICENSE`."
1068
+ },
1069
+ "immutable": true,
1070
+ "locationInModule": {
1071
+ "filename": "src/cdk/options.ts",
1072
+ "line": 43
1073
+ },
1074
+ "name": "license",
1075
+ "optional": true,
1076
+ "type": {
1077
+ "primitive": "string"
1078
+ }
1079
+ },
1080
+ {
1081
+ "abstract": true,
1082
+ "docs": {
1083
+ "default": "true",
1084
+ "stability": "experimental",
1085
+ "summary": "Write a `LICENSE`."
1086
+ },
1087
+ "immutable": true,
1088
+ "locationInModule": {
1089
+ "filename": "src/cdk/options.ts",
1090
+ "line": 37
1091
+ },
1092
+ "name": "licensed",
1093
+ "optional": true,
1094
+ "type": {
1095
+ "primitive": "boolean"
1096
+ }
1107
1097
  }
1108
1098
  ],
1109
1099
  "symbolId": "src/cdk/options:CommonCdkOptions"
@@ -1115,10 +1105,13 @@
1115
1105
  "stability": "experimental"
1116
1106
  },
1117
1107
  "fqn": "@xpertss/projen-types.CommonJavaOptions",
1108
+ "interfaces": [
1109
+ "@xpertss/projen-types.SonarScanOptions"
1110
+ ],
1118
1111
  "kind": "interface",
1119
1112
  "locationInModule": {
1120
1113
  "filename": "src/java/options.ts",
1121
- "line": 3
1114
+ "line": 4
1122
1115
  },
1123
1116
  "name": "CommonJavaOptions",
1124
1117
  "properties": [
@@ -1130,7 +1123,7 @@
1130
1123
  "immutable": true,
1131
1124
  "locationInModule": {
1132
1125
  "filename": "src/java/options.ts",
1133
- "line": 6
1126
+ "line": 7
1134
1127
  },
1135
1128
  "name": "artifactId",
1136
1129
  "type": {
@@ -1145,7 +1138,7 @@
1145
1138
  "immutable": true,
1146
1139
  "locationInModule": {
1147
1140
  "filename": "src/java/options.ts",
1148
- "line": 5
1141
+ "line": 6
1149
1142
  },
1150
1143
  "name": "groupId",
1151
1144
  "type": {
@@ -1160,7 +1153,7 @@
1160
1153
  "immutable": true,
1161
1154
  "locationInModule": {
1162
1155
  "filename": "src/java/options.ts",
1163
- "line": 4
1156
+ "line": 5
1164
1157
  },
1165
1158
  "name": "name",
1166
1159
  "type": {
@@ -1170,14 +1163,14 @@
1170
1163
  {
1171
1164
  "abstract": true,
1172
1165
  "docs": {
1173
- "default": "\"xpertss\" (same as `GitHubActionProject`)",
1166
+ "default": "\"Xpert Software\"",
1174
1167
  "stability": "experimental",
1175
1168
  "summary": "Copyright owner named in the `LICENSE`."
1176
1169
  },
1177
1170
  "immutable": true,
1178
1171
  "locationInModule": {
1179
1172
  "filename": "src/java/options.ts",
1180
- "line": 103
1173
+ "line": 101
1181
1174
  },
1182
1175
  "name": "copyrightOwner",
1183
1176
  "optional": true,
@@ -1195,7 +1188,7 @@
1195
1188
  "immutable": true,
1196
1189
  "locationInModule": {
1197
1190
  "filename": "src/java/options.ts",
1198
- "line": 109
1191
+ "line": 107
1199
1192
  },
1200
1193
  "name": "copyrightPeriod",
1201
1194
  "optional": true,
@@ -1213,7 +1206,7 @@
1213
1206
  "immutable": true,
1214
1207
  "locationInModule": {
1215
1208
  "filename": "src/java/options.ts",
1216
- "line": 12
1209
+ "line": 13
1217
1210
  },
1218
1211
  "name": "description",
1219
1212
  "optional": true,
@@ -1231,7 +1224,7 @@
1231
1224
  "immutable": true,
1232
1225
  "locationInModule": {
1233
1226
  "filename": "src/java/options.ts",
1234
- "line": 115
1227
+ "line": 113
1235
1228
  },
1236
1229
  "name": "editorconfig",
1237
1230
  "optional": true,
@@ -1250,7 +1243,7 @@
1250
1243
  "immutable": true,
1251
1244
  "locationInModule": {
1252
1245
  "filename": "src/java/options.ts",
1253
- "line": 67
1246
+ "line": 65
1254
1247
  },
1255
1248
  "name": "enforcer",
1256
1249
  "optional": true,
@@ -1267,7 +1260,7 @@
1267
1260
  "immutable": true,
1268
1261
  "locationInModule": {
1269
1262
  "filename": "src/java/options.ts",
1270
- "line": 21
1263
+ "line": 19
1271
1264
  },
1272
1265
  "name": "gheTokenSecret",
1273
1266
  "optional": true,
@@ -1285,7 +1278,7 @@
1285
1278
  "immutable": true,
1286
1279
  "locationInModule": {
1287
1280
  "filename": "src/java/options.ts",
1288
- "line": 40
1281
+ "line": 38
1289
1282
  },
1290
1283
  "name": "javaDistribution",
1291
1284
  "optional": true,
@@ -1304,7 +1297,7 @@
1304
1297
  "immutable": true,
1305
1298
  "locationInModule": {
1306
1299
  "filename": "src/java/options.ts",
1307
- "line": 34
1300
+ "line": 32
1308
1301
  },
1309
1302
  "name": "javaVersion",
1310
1303
  "optional": true,
@@ -1322,7 +1315,7 @@
1322
1315
  "immutable": true,
1323
1316
  "locationInModule": {
1324
1317
  "filename": "src/java/options.ts",
1325
- "line": 97
1318
+ "line": 95
1326
1319
  },
1327
1320
  "name": "license",
1328
1321
  "optional": true,
@@ -1340,7 +1333,7 @@
1340
1333
  "immutable": true,
1341
1334
  "locationInModule": {
1342
1335
  "filename": "src/java/options.ts",
1343
- "line": 91
1336
+ "line": 89
1344
1337
  },
1345
1338
  "name": "licensed",
1346
1339
  "optional": true,
@@ -1359,7 +1352,7 @@
1359
1352
  "immutable": true,
1360
1353
  "locationInModule": {
1361
1354
  "filename": "src/java/options.ts",
1362
- "line": 75
1355
+ "line": 73
1363
1356
  },
1364
1357
  "name": "minMavenVersion",
1365
1358
  "optional": true,
@@ -1378,7 +1371,7 @@
1378
1371
  "immutable": true,
1379
1372
  "locationInModule": {
1380
1373
  "filename": "src/java/options.ts",
1381
- "line": 49
1374
+ "line": 47
1382
1375
  },
1383
1376
  "name": "packaging",
1384
1377
  "optional": true,
@@ -1396,7 +1389,7 @@
1396
1389
  "immutable": true,
1397
1390
  "locationInModule": {
1398
1391
  "filename": "src/java/options.ts",
1399
- "line": 85
1392
+ "line": 83
1400
1393
  },
1401
1394
  "name": "pluginVersions",
1402
1395
  "optional": true,
@@ -1420,7 +1413,7 @@
1420
1413
  "immutable": true,
1421
1414
  "locationInModule": {
1422
1415
  "filename": "src/java/options.ts",
1423
- "line": 57
1416
+ "line": 55
1424
1417
  },
1425
1418
  "name": "sample",
1426
1419
  "optional": true,
@@ -1428,24 +1421,6 @@
1428
1421
  "primitive": "boolean"
1429
1422
  }
1430
1423
  },
1431
- {
1432
- "abstract": true,
1433
- "docs": {
1434
- "remarks": "If unset, the sonar scan step is skipped.",
1435
- "stability": "experimental",
1436
- "summary": "SonarCloud project key."
1437
- },
1438
- "immutable": true,
1439
- "locationInModule": {
1440
- "filename": "src/java/options.ts",
1441
- "line": 18
1442
- },
1443
- "name": "sonarProjectKey",
1444
- "optional": true,
1445
- "type": {
1446
- "primitive": "string"
1447
- }
1448
- },
1449
1424
  {
1450
1425
  "abstract": true,
1451
1426
  "docs": {
@@ -1456,7 +1431,7 @@
1456
1431
  "immutable": true,
1457
1432
  "locationInModule": {
1458
1433
  "filename": "src/java/options.ts",
1459
- "line": 124
1434
+ "line": 122
1460
1435
  },
1461
1436
  "name": "upgradeWorkflow",
1462
1437
  "optional": true,
@@ -1474,7 +1449,7 @@
1474
1449
  "immutable": true,
1475
1450
  "locationInModule": {
1476
1451
  "filename": "src/java/options.ts",
1477
- "line": 15
1452
+ "line": 16
1478
1453
  },
1479
1454
  "name": "url",
1480
1455
  "optional": true,
@@ -1491,7 +1466,7 @@
1491
1466
  "immutable": true,
1492
1467
  "locationInModule": {
1493
1468
  "filename": "src/java/options.ts",
1494
- "line": 9
1469
+ "line": 10
1495
1470
  },
1496
1471
  "name": "version",
1497
1472
  "optional": true,
@@ -1553,7 +1528,7 @@
1553
1528
  "kind": "interface",
1554
1529
  "locationInModule": {
1555
1530
  "filename": "src/cdk/options.ts",
1556
- "line": 60
1531
+ "line": 85
1557
1532
  },
1558
1533
  "name": "DatabaseOptions",
1559
1534
  "properties": [
@@ -1566,7 +1541,7 @@
1566
1541
  "immutable": true,
1567
1542
  "locationInModule": {
1568
1543
  "filename": "src/cdk/options.ts",
1569
- "line": 62
1544
+ "line": 87
1570
1545
  },
1571
1546
  "name": "engine",
1572
1547
  "optional": true,
@@ -1583,7 +1558,7 @@
1583
1558
  "immutable": true,
1584
1559
  "locationInModule": {
1585
1560
  "filename": "src/cdk/options.ts",
1586
- "line": 65
1561
+ "line": 90
1587
1562
  },
1588
1563
  "name": "migrationTool",
1589
1564
  "optional": true,
@@ -1719,7 +1694,7 @@
1719
1694
  "kind": "interface",
1720
1695
  "locationInModule": {
1721
1696
  "filename": "src/cdk/options.ts",
1722
- "line": 10
1697
+ "line": 11
1723
1698
  },
1724
1699
  "name": "EcrEcsOptions",
1725
1700
  "properties": [
@@ -1732,7 +1707,7 @@
1732
1707
  "immutable": true,
1733
1708
  "locationInModule": {
1734
1709
  "filename": "src/cdk/options.ts",
1735
- "line": 12
1710
+ "line": 13
1736
1711
  },
1737
1712
  "name": "enabled",
1738
1713
  "optional": true,
@@ -1750,7 +1725,7 @@
1750
1725
  "immutable": true,
1751
1726
  "locationInModule": {
1752
1727
  "filename": "src/cdk/options.ts",
1753
- "line": 20
1728
+ "line": 21
1754
1729
  },
1755
1730
  "name": "externalImageSource",
1756
1731
  "optional": true,
@@ -1939,7 +1914,7 @@
1939
1914
  },
1940
1915
  "locationInModule": {
1941
1916
  "filename": "src/actions/github-action-project.ts",
1942
- "line": 149
1917
+ "line": 141
1943
1918
  },
1944
1919
  "parameters": [
1945
1920
  {
@@ -1953,7 +1928,7 @@
1953
1928
  "kind": "class",
1954
1929
  "locationInModule": {
1955
1930
  "filename": "src/actions/github-action-project.ts",
1956
- "line": 143
1931
+ "line": 134
1957
1932
  },
1958
1933
  "name": "GitHubActionProject",
1959
1934
  "properties": [
@@ -1964,7 +1939,7 @@
1964
1939
  "immutable": true,
1965
1940
  "locationInModule": {
1966
1941
  "filename": "src/actions/github-action-project.ts",
1967
- "line": 144
1942
+ "line": 135
1968
1943
  },
1969
1944
  "name": "buildWorkflow",
1970
1945
  "type": {
@@ -1978,7 +1953,7 @@
1978
1953
  "immutable": true,
1979
1954
  "locationInModule": {
1980
1955
  "filename": "src/actions/github-action-project.ts",
1981
- "line": 145
1956
+ "line": 136
1982
1957
  },
1983
1958
  "name": "dogfoodWorkflow",
1984
1959
  "type": {
@@ -1992,7 +1967,7 @@
1992
1967
  "immutable": true,
1993
1968
  "locationInModule": {
1994
1969
  "filename": "src/actions/github-action-project.ts",
1995
- "line": 147
1970
+ "line": 139
1996
1971
  },
1997
1972
  "name": "release",
1998
1973
  "type": {
@@ -2001,16 +1976,18 @@
2001
1976
  },
2002
1977
  {
2003
1978
  "docs": {
2004
- "stability": "experimental"
1979
+ "stability": "experimental",
1980
+ "summary": "Set only when `sonarHostUrl` is provided."
2005
1981
  },
2006
1982
  "immutable": true,
2007
1983
  "locationInModule": {
2008
1984
  "filename": "src/actions/github-action-project.ts",
2009
- "line": 146
1985
+ "line": 138
2010
1986
  },
2011
1987
  "name": "sonarWorkflow",
1988
+ "optional": true,
2012
1989
  "type": {
2013
- "fqn": "@xpertss/projen-types.ActionSonarWorkflow"
1990
+ "fqn": "@xpertss/projen-types.SonarWorkflow"
2014
1991
  }
2015
1992
  }
2016
1993
  ],
@@ -2024,27 +2001,48 @@
2024
2001
  },
2025
2002
  "fqn": "@xpertss/projen-types.GitHubActionProjectOptions",
2026
2003
  "interfaces": [
2027
- "projen.github.GitHubProjectOptions"
2004
+ "projen.github.GitHubProjectOptions",
2005
+ "@xpertss/projen-types.SonarScanOptions"
2028
2006
  ],
2029
2007
  "kind": "interface",
2030
2008
  "locationInModule": {
2031
2009
  "filename": "src/actions/github-action-project.ts",
2032
- "line": 36
2010
+ "line": 37
2033
2011
  },
2034
2012
  "name": "GitHubActionProjectOptions",
2035
2013
  "properties": [
2036
2014
  {
2037
2015
  "abstract": true,
2038
2016
  "docs": {
2017
+ "default": "\"Xpert Software\"",
2039
2018
  "stability": "experimental",
2040
- "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."
2019
+ "summary": "Copyright owner named in the `LICENSE`."
2041
2020
  },
2042
2021
  "immutable": true,
2043
2022
  "locationInModule": {
2044
2023
  "filename": "src/actions/github-action-project.ts",
2045
- "line": 59
2024
+ "line": 83
2046
2025
  },
2047
- "name": "sonarHostUrl",
2026
+ "name": "copyrightOwner",
2027
+ "optional": true,
2028
+ "type": {
2029
+ "primitive": "string"
2030
+ }
2031
+ },
2032
+ {
2033
+ "abstract": true,
2034
+ "docs": {
2035
+ "default": "- the current year",
2036
+ "stability": "experimental",
2037
+ "summary": "Copyright period named in the `LICENSE`."
2038
+ },
2039
+ "immutable": true,
2040
+ "locationInModule": {
2041
+ "filename": "src/actions/github-action-project.ts",
2042
+ "line": 89
2043
+ },
2044
+ "name": "copyrightPeriod",
2045
+ "optional": true,
2048
2046
  "type": {
2049
2047
  "primitive": "string"
2050
2048
  }
@@ -2059,7 +2057,7 @@
2059
2057
  "immutable": true,
2060
2058
  "locationInModule": {
2061
2059
  "filename": "src/actions/github-action-project.ts",
2062
- "line": 42
2060
+ "line": 44
2063
2061
  },
2064
2062
  "name": "description",
2065
2063
  "optional": true,
@@ -2078,7 +2076,7 @@
2078
2076
  "immutable": true,
2079
2077
  "locationInModule": {
2080
2078
  "filename": "src/actions/github-action-project.ts",
2081
- "line": 92
2079
+ "line": 71
2082
2080
  },
2083
2081
  "name": "dogfood",
2084
2082
  "optional": true,
@@ -2096,7 +2094,7 @@
2096
2094
  "immutable": true,
2097
2095
  "locationInModule": {
2098
2096
  "filename": "src/actions/github-action-project.ts",
2099
- "line": 104
2097
+ "line": 95
2100
2098
  },
2101
2099
  "name": "editorconfig",
2102
2100
  "optional": true,
@@ -2115,7 +2113,7 @@
2115
2113
  "immutable": true,
2116
2114
  "locationInModule": {
2117
2115
  "filename": "src/actions/github-action-project.ts",
2118
- "line": 52
2116
+ "line": 54
2119
2117
  },
2120
2118
  "name": "gheTokenSecret",
2121
2119
  "optional": true,
@@ -2133,66 +2131,13 @@
2133
2131
  "immutable": true,
2134
2132
  "locationInModule": {
2135
2133
  "filename": "src/actions/github-action-project.ts",
2136
- "line": 98
2134
+ "line": 77
2137
2135
  },
2138
2136
  "name": "license",
2139
2137
  "optional": true,
2140
2138
  "type": {
2141
2139
  "primitive": "string"
2142
2140
  }
2143
- },
2144
- {
2145
- "abstract": true,
2146
- "docs": {
2147
- "default": "\"xpertss\"",
2148
- "stability": "experimental",
2149
- "summary": "SonarCloud organization key (`sonar.organization`), required by the Scanner CLI on SonarCloud."
2150
- },
2151
- "immutable": true,
2152
- "locationInModule": {
2153
- "filename": "src/actions/github-action-project.ts",
2154
- "line": 66
2155
- },
2156
- "name": "sonarOrganization",
2157
- "optional": true,
2158
- "type": {
2159
- "primitive": "string"
2160
- }
2161
- },
2162
- {
2163
- "abstract": true,
2164
- "docs": {
2165
- "default": "true",
2166
- "stability": "experimental",
2167
- "summary": "Whether `sonar.yml` also runs on `pull_request` as a pass/fail gate."
2168
- },
2169
- "immutable": true,
2170
- "locationInModule": {
2171
- "filename": "src/actions/github-action-project.ts",
2172
- "line": 75
2173
- },
2174
- "name": "sonarPullRequestGate",
2175
- "optional": true,
2176
- "type": {
2177
- "primitive": "boolean"
2178
- }
2179
- },
2180
- {
2181
- "abstract": true,
2182
- "docs": {
2183
- "default": "\"SONAR_TOKEN\"",
2184
- "stability": "experimental"
2185
- },
2186
- "immutable": true,
2187
- "locationInModule": {
2188
- "filename": "src/actions/github-action-project.ts",
2189
- "line": 69
2190
- },
2191
- "name": "sonarTokenSecret",
2192
- "optional": true,
2193
- "type": {
2194
- "primitive": "string"
2195
- }
2196
2141
  }
2197
2142
  ],
2198
2143
  "symbolId": "src/actions/github-action-project:GitHubActionProjectOptions"
@@ -2318,7 +2263,7 @@
2318
2263
  "kind": "interface",
2319
2264
  "locationInModule": {
2320
2265
  "filename": "src/java/options.ts",
2321
- "line": 201
2266
+ "line": 199
2322
2267
  },
2323
2268
  "name": "JavaAppProjectOptions",
2324
2269
  "properties": [
@@ -2331,7 +2276,7 @@
2331
2276
  "immutable": true,
2332
2277
  "locationInModule": {
2333
2278
  "filename": "src/java/options.ts",
2334
- "line": 203
2279
+ "line": 201
2335
2280
  },
2336
2281
  "name": "ghPackagesRegistry",
2337
2282
  "optional": true,
@@ -2389,7 +2334,7 @@
2389
2334
  "kind": "interface",
2390
2335
  "locationInModule": {
2391
2336
  "filename": "src/java/options.ts",
2392
- "line": 144
2337
+ "line": 142
2393
2338
  },
2394
2339
  "name": "JavaLibraryProjectOptions",
2395
2340
  "properties": [
@@ -2402,7 +2347,7 @@
2402
2347
  "immutable": true,
2403
2348
  "locationInModule": {
2404
2349
  "filename": "src/java/options.ts",
2405
- "line": 146
2350
+ "line": 144
2406
2351
  },
2407
2352
  "name": "mavenCentralOidc",
2408
2353
  "optional": true,
@@ -2419,7 +2364,7 @@
2419
2364
  "immutable": true,
2420
2365
  "locationInModule": {
2421
2366
  "filename": "src/java/options.ts",
2422
- "line": 149
2367
+ "line": 147
2423
2368
  },
2424
2369
  "name": "publishCodeIndex",
2425
2370
  "optional": true,
@@ -2434,7 +2379,7 @@
2434
2379
  "assembly": "@xpertss/projen-types",
2435
2380
  "base": "projen.github.GitHubProject",
2436
2381
  "docs": {
2437
- "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.",
2438
2383
  "stability": "experimental",
2439
2384
  "summary": "Baseline Maven project, single- or multi-module, with no framework assumptions."
2440
2385
  },
@@ -2445,7 +2390,7 @@
2445
2390
  },
2446
2391
  "locationInModule": {
2447
2392
  "filename": "src/java/java-maven-base.ts",
2448
- "line": 85
2393
+ "line": 90
2449
2394
  },
2450
2395
  "parameters": [
2451
2396
  {
@@ -2459,7 +2404,7 @@
2459
2404
  "kind": "class",
2460
2405
  "locationInModule": {
2461
2406
  "filename": "src/java/java-maven-base.ts",
2462
- "line": 56
2407
+ "line": 58
2463
2408
  },
2464
2409
  "methods": [
2465
2410
  {
@@ -2469,7 +2414,7 @@
2469
2414
  },
2470
2415
  "locationInModule": {
2471
2416
  "filename": "src/java/java-maven-base.ts",
2472
- "line": 275
2417
+ "line": 280
2473
2418
  },
2474
2419
  "name": "addBom",
2475
2420
  "parameters": [
@@ -2492,7 +2437,7 @@
2492
2437
  },
2493
2438
  "locationInModule": {
2494
2439
  "filename": "src/java/java-maven-base.ts",
2495
- "line": 297
2440
+ "line": 302
2496
2441
  },
2497
2442
  "name": "addDependency",
2498
2443
  "parameters": [
@@ -2514,7 +2459,7 @@
2514
2459
  },
2515
2460
  "locationInModule": {
2516
2461
  "filename": "src/java/java-maven-base.ts",
2517
- "line": 285
2462
+ "line": 290
2518
2463
  },
2519
2464
  "name": "addManagedDependency",
2520
2465
  "parameters": [
@@ -2537,7 +2482,7 @@
2537
2482
  },
2538
2483
  "locationInModule": {
2539
2484
  "filename": "src/java/java-maven-base.ts",
2540
- "line": 244
2485
+ "line": 249
2541
2486
  },
2542
2487
  "name": "addModule",
2543
2488
  "parameters": [
@@ -2561,7 +2506,7 @@
2561
2506
  },
2562
2507
  "locationInModule": {
2563
2508
  "filename": "src/java/java-maven-base.ts",
2564
- "line": 307
2509
+ "line": 312
2565
2510
  },
2566
2511
  "name": "addPlugin",
2567
2512
  "parameters": [
@@ -2587,7 +2532,7 @@
2587
2532
  },
2588
2533
  "locationInModule": {
2589
2534
  "filename": "src/java/java-maven-base.ts",
2590
- "line": 302
2535
+ "line": 307
2591
2536
  },
2592
2537
  "name": "addTestDependency",
2593
2538
  "parameters": [
@@ -2606,7 +2551,7 @@
2606
2551
  },
2607
2552
  "locationInModule": {
2608
2553
  "filename": "src/java/java-maven-base.ts",
2609
- "line": 335
2554
+ "line": 340
2610
2555
  },
2611
2556
  "name": "maxSpringBootMajor",
2612
2557
  "protected": true,
@@ -2624,7 +2569,7 @@
2624
2569
  },
2625
2570
  "locationInModule": {
2626
2571
  "filename": "src/java/java-maven-base.ts",
2627
- "line": 323
2572
+ "line": 328
2628
2573
  },
2629
2574
  "name": "pinnedVersion",
2630
2575
  "parameters": [
@@ -2648,7 +2593,7 @@
2648
2593
  },
2649
2594
  "locationInModule": {
2650
2595
  "filename": "src/java/java-maven-base.ts",
2651
- "line": 311
2596
+ "line": 316
2652
2597
  },
2653
2598
  "name": "preSynthesize",
2654
2599
  "overrides": "projen.Project"
@@ -2664,7 +2609,7 @@
2664
2609
  "immutable": true,
2665
2610
  "locationInModule": {
2666
2611
  "filename": "src/java/java-maven-base.ts",
2667
- "line": 71
2612
+ "line": 73
2668
2613
  },
2669
2614
  "name": "buildVerifyWorkflow",
2670
2615
  "type": {
@@ -2679,7 +2624,7 @@
2679
2624
  "immutable": true,
2680
2625
  "locationInModule": {
2681
2626
  "filename": "src/java/java-maven-base.ts",
2682
- "line": 77
2627
+ "line": 79
2683
2628
  },
2684
2629
  "name": "ciSetupSteps",
2685
2630
  "type": {
@@ -2699,7 +2644,7 @@
2699
2644
  "immutable": true,
2700
2645
  "locationInModule": {
2701
2646
  "filename": "src/java/java-maven-base.ts",
2702
- "line": 61
2647
+ "line": 63
2703
2648
  },
2704
2649
  "name": "javaVersion",
2705
2650
  "type": {
@@ -2714,7 +2659,7 @@
2714
2659
  "immutable": true,
2715
2660
  "locationInModule": {
2716
2661
  "filename": "src/java/java-maven-base.ts",
2717
- "line": 233
2662
+ "line": 238
2718
2663
  },
2719
2664
  "name": "modules",
2720
2665
  "type": {
@@ -2734,26 +2679,42 @@
2734
2679
  "immutable": true,
2735
2680
  "locationInModule": {
2736
2681
  "filename": "src/java/java-maven-base.ts",
2737
- "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
2738
2698
  },
2739
- "name": "pom",
2699
+ "name": "upgradeTask",
2740
2700
  "type": {
2741
- "fqn": "@xpertss/projen-types.MavenPom"
2701
+ "fqn": "projen.Task"
2742
2702
  }
2743
2703
  },
2744
2704
  {
2745
2705
  "docs": {
2746
2706
  "stability": "experimental",
2747
- "summary": "Prints available dependency/plugin updates (`npx projen upgrade`)."
2707
+ "summary": "Set only when `sonarHostUrl` is provided."
2748
2708
  },
2749
2709
  "immutable": true,
2750
2710
  "locationInModule": {
2751
2711
  "filename": "src/java/java-maven-base.ts",
2752
- "line": 64
2712
+ "line": 82
2753
2713
  },
2754
- "name": "upgradeTask",
2714
+ "name": "sonarWorkflow",
2715
+ "optional": true,
2755
2716
  "type": {
2756
- "fqn": "projen.Task"
2717
+ "fqn": "@xpertss/projen-types.SonarWorkflow"
2757
2718
  }
2758
2719
  }
2759
2720
  ],
@@ -2773,7 +2734,7 @@
2773
2734
  "kind": "interface",
2774
2735
  "locationInModule": {
2775
2736
  "filename": "src/java/options.ts",
2776
- "line": 128
2737
+ "line": 126
2777
2738
  },
2778
2739
  "name": "JavaMavenProjectOptions",
2779
2740
  "symbolId": "src/java/options:JavaMavenProjectOptions"
@@ -2853,7 +2814,7 @@
2853
2814
  "kind": "interface",
2854
2815
  "locationInModule": {
2855
2816
  "filename": "src/java/options.ts",
2856
- "line": 163
2817
+ "line": 161
2857
2818
  },
2858
2819
  "name": "JavaServiceProjectOptions",
2859
2820
  "properties": [
@@ -2867,7 +2828,7 @@
2867
2828
  "immutable": true,
2868
2829
  "locationInModule": {
2869
2830
  "filename": "src/java/options.ts",
2870
- "line": 190
2831
+ "line": 188
2871
2832
  },
2872
2833
  "name": "cdkDeployHook",
2873
2834
  "optional": true,
@@ -2889,7 +2850,7 @@
2889
2850
  "immutable": true,
2890
2851
  "locationInModule": {
2891
2852
  "filename": "src/java/options.ts",
2892
- "line": 183
2853
+ "line": 181
2893
2854
  },
2894
2855
  "name": "cdkDeployTargetRepo",
2895
2856
  "optional": true,
@@ -2906,7 +2867,7 @@
2906
2867
  "immutable": true,
2907
2868
  "locationInModule": {
2908
2869
  "filename": "src/java/options.ts",
2909
- "line": 165
2870
+ "line": 163
2910
2871
  },
2911
2872
  "name": "dockerRegistry",
2912
2873
  "optional": true,
@@ -2924,7 +2885,7 @@
2924
2885
  "immutable": true,
2925
2886
  "locationInModule": {
2926
2887
  "filename": "src/java/options.ts",
2927
- "line": 198
2888
+ "line": 196
2928
2889
  },
2929
2890
  "name": "environments",
2930
2891
  "optional": true,
@@ -2955,7 +2916,7 @@
2955
2916
  "immutable": true,
2956
2917
  "locationInModule": {
2957
2918
  "filename": "src/java/options.ts",
2958
- "line": 168
2919
+ "line": 166
2959
2920
  },
2960
2921
  "name": "useFlyway",
2961
2922
  "optional": true,
@@ -3069,7 +3030,7 @@
3069
3030
  "kind": "interface",
3070
3031
  "locationInModule": {
3071
3032
  "filename": "src/java/options.ts",
3072
- "line": 131
3033
+ "line": 129
3073
3034
  },
3074
3035
  "name": "JavaSpringBootProjectOptions",
3075
3036
  "properties": [
@@ -3084,7 +3045,7 @@
3084
3045
  "immutable": true,
3085
3046
  "locationInModule": {
3086
3047
  "filename": "src/java/options.ts",
3087
- "line": 141
3048
+ "line": 139
3088
3049
  },
3089
3050
  "name": "springBootVersion",
3090
3051
  "optional": true,
@@ -3439,7 +3400,7 @@
3439
3400
  "kind": "interface",
3440
3401
  "locationInModule": {
3441
3402
  "filename": "src/java/options.ts",
3442
- "line": 207
3403
+ "line": 205
3443
3404
  },
3444
3405
  "name": "MavenModuleOptions",
3445
3406
  "properties": [
@@ -3451,7 +3412,7 @@
3451
3412
  "immutable": true,
3452
3413
  "locationInModule": {
3453
3414
  "filename": "src/java/options.ts",
3454
- "line": 214
3415
+ "line": 212
3455
3416
  },
3456
3417
  "name": "artifactId",
3457
3418
  "type": {
@@ -3467,7 +3428,7 @@
3467
3428
  "immutable": true,
3468
3429
  "locationInModule": {
3469
3430
  "filename": "src/java/options.ts",
3470
- "line": 212
3431
+ "line": 210
3471
3432
  },
3472
3433
  "name": "dir",
3473
3434
  "type": {
@@ -3483,7 +3444,7 @@
3483
3444
  "immutable": true,
3484
3445
  "locationInModule": {
3485
3446
  "filename": "src/java/options.ts",
3486
- "line": 220
3447
+ "line": 218
3487
3448
  },
3488
3449
  "name": "description",
3489
3450
  "optional": true,
@@ -3500,7 +3461,7 @@
3500
3461
  "immutable": true,
3501
3462
  "locationInModule": {
3502
3463
  "filename": "src/java/options.ts",
3503
- "line": 217
3464
+ "line": 215
3504
3465
  },
3505
3466
  "name": "name",
3506
3467
  "optional": true,
@@ -3517,7 +3478,7 @@
3517
3478
  "immutable": true,
3518
3479
  "locationInModule": {
3519
3480
  "filename": "src/java/options.ts",
3520
- "line": 223
3481
+ "line": 221
3521
3482
  },
3522
3483
  "name": "packaging",
3523
3484
  "optional": true,
@@ -4407,6 +4368,289 @@
4407
4368
  ],
4408
4369
  "symbolId": "src/common/projen-drift-check-workflow:ProjenDriftCheckWorkflowOptions"
4409
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
+ },
4410
4654
  "@xpertss/projen-types.WorkflowChangeNoticeWorkflow": {
4411
4655
  "assembly": "@xpertss/projen-types",
4412
4656
  "base": "projen.Component",
@@ -4522,6 +4766,6 @@
4522
4766
  "symbolId": "src/common/workflow-change-notice-workflow:WorkflowChangeNoticeWorkflowOptions"
4523
4767
  }
4524
4768
  },
4525
- "version": "0.0.20",
4526
- "fingerprint": "MHILgc1SAeQshgKcGrobju334X9PfXuY4a/KjK6JNJ8="
4769
+ "version": "0.0.22",
4770
+ "fingerprint": "X29Pe4ieYhnrNjcCkP20geT95pIeT0dvl9TcMcDDd1A="
4527
4771
  }