diff --git a/docs/advanced/operating-in-ci.md b/docs/advanced/operating-in-ci.md index 559c958..9cb65ad 100644 --- a/docs/advanced/operating-in-ci.md +++ b/docs/advanced/operating-in-ci.md @@ -57,7 +57,7 @@ Stage 1 writes `runtime/bundle.tgz` for one environment. Stages 2, 3, 5, 6, 7 an The mode is a build parameter and defaults to **`dry-run`** on Jenkins. Stage 6 plans with it and stage 7 applies with it, so the plan is for the mode that is applied. After a dry-run apply, stage 8 downgrades to `--mode check`, and stages 9, 10 and 11 print that stage 7 applied nothing and skip. To deploy, run with `APPLY_MODE` set to `amend` or `amend-and-build`. -`--build-id` is passed to apply only for `amend-and-build` and `replace-and-build`, from `APPLY_BUILD_ID` (blank runs every build). With any other mode the stage prints that `APPLY_BUILD_ID` is not passed on and carries on. Calling `fluid apply` by hand with `--build-id` and a mode that runs no build is refused with `apply_build_id_requires_build_mode`. +`--build-id` is passed to apply only for `amend-and-build` and `replace-and-build`, from `APPLY_BUILD_ID` (blank runs every build). With any other mode the stage prints that `APPLY_BUILD_ID` is not passed on and carries on. Calling `fluid apply` by hand with `--build-id` and a mode that runs no build is refused with `apply_build_id_requires_build_mode`. *(On forge-cli `main`, not yet in a release, [forge-cli #808](https://github.com/Agenticstiger/forge-cli/pull/808).)* An `APPLY_BUILD_ID` that matches none of the contract's builds fails stage 7 with `apply_build_id_not_found` before it applies anything. ::: details Stage 3 and fragment-layout contracts Stage 3 reads the bundle, not the contract file. As of 0.18.1, `fluid generate artifacts contract.fluid.yaml` on a fragment-layout contract (one whose `exposes` come from `$ref` files) without `--env` fails with `Provider error: FLUID expose has no usable name`. With `--env`, or given the stage-1 bundle, it succeeds. The generated pipeline uses the bundle, so it is not affected; a hand-written step that passes the contract path is. diff --git a/docs/advanced/production-troubleshooting.md b/docs/advanced/production-troubleshooting.md index 4ef5063..e607aa3 100644 --- a/docs/advanced/production-troubleshooting.md +++ b/docs/advanced/production-troubleshooting.md @@ -64,6 +64,8 @@ When the bundle is unrecoverable, `fluid apply --no-verify-plan-binding` skips t | `bundle_env_mismatch` | A bundle is built for one env and is never re-overlaid. A later stage was asked for another `--env` | Rebuild with `fluid bundle --env --format tgz`, or pass the env the bundle was built for | | `plan_env_mismatch` | A plan records the env it was made for, and an `*-and-build` apply was given a different `--env` | Apply with the recorded env (or without `--env`), or re-plan with the env you want | | `apply_build_id_requires_build_mode` | `--build-id` selects which build runs, and the mode (for example `dry-run`) runs none | Use `--mode amend-and-build` or `replace-and-build`, or drop `--build-id` | +| `apply_build_identifier_invalid` | *(On forge-cli `main`, not yet in a release, [forge-cli #803](https://github.com/Agenticstiger/forge-cli/pull/803).)* A build mode, and an `id` or `builds[].id` the build phase cannot use. It must start with a letter or `_`, use only letters, digits, `_`, `.` and `-`, and be at most 128 characters; the schema accepts more, so `fluid validate` passes it. Nothing is applied | Rename the id and apply again. See [Build ids](../cli/apply.md#build-ids) for what a rename resets | +| `apply_build_id_not_found` | *(On forge-cli `main`, not yet in a release, [forge-cli #808](https://github.com/Agenticstiger/forge-cli/pull/808).)* A build mode was given a `--build-id` that matches none of the contract's `builds[].id`. Ids match exactly, case and spaces included. Nothing is applied | Pass one of the ids the error lists as `available`, or drop `--build-id` to run every build. See [Build ids](../cli/apply.md#build-ids) | | `apply_plan_unreadable` | The plan file is missing, is not JSON, or is truncated | Regenerate it with `fluid plan --out` | | `apply_plan_mode_mismatch` | The plan was made for a different `--mode` than apply was given | Re-run `fluid plan --mode ` with the mode you will apply | | `apply_contract_invalid` | *(since 0.20.0, [forge-cli #714](https://github.com/Agenticstiger/forge-cli/pull/714))* The contract, or the contract a `plan.json` embeds, is not valid against its schema; the `errors:` line lists why. `fluid apply` checks it on both engines and in every mode, so a cloud or build apply that used to exit 0 on such a contract now stops here | Run `fluid validate --env `, fix what it reports, and apply again. No flag skips the check. See [Contract validation](../cli/apply.md#contract-validation) | diff --git a/docs/cli/apply.md b/docs/cli/apply.md index 429ab45..4dfeaec 100644 --- a/docs/cli/apply.md +++ b/docs/cli/apply.md @@ -220,6 +220,25 @@ fluid apply contract.fluid.yaml --mode amend-and-build --yes Before this change only the build runner checked these ids. On the OpenTofu engine the runner starts after `tofu apply`, so the product was provisioned first, and the run then stopped with "Unexpected error". A mode without a build phase is not checked, and neither is a contract without `builds`. +*On forge-cli `main`, not yet in a release ([forge-cli #808](https://github.com/Agenticstiger/forge-cli/pull/808)).* Right after that check, `fluid apply` makes sure a `--build-id` names one of the contract's builds. Ids match exactly, case and spaces included, as they do in the build runner. A `--build-id` that matches no `builds[].id` is refused on both engines, before the apply hooks, `tofu` and any build, and the refusal lists the ids the contract has: + +```bash +fluid apply contract.fluid.yaml --mode amend-and-build --build-id make_row --yes +``` + +```text +❌ apply_build_id_not_found [ERR_APPLY_BUILD_ID_NOT_FOUND] + build_id: 'make_row' + available: ['make_rows'] + hint: --build-id selects the build whose id equals it exactly, case and spaces included, and no build of the contract has that id. Pass one of the available ids, or drop --build-id to run every build. Nothing was applied. + +💡 Suggestions: + • Pass one of the available build ids as --build-id: ids match exactly, case included + • Run 'fluid apply --mode amend-and-build' without --build-id to run every build +``` + +Before this change the build runner was the only check. On the OpenTofu engine it starts after `tofu apply`, so a mistyped `--build-id` provisioned the product, and the run then stopped with `Build not found` and exit 1. An empty `--build-id` still runs every build, and a contract without `builds` is still not checked. + ## Plan binding When you pass a saved plan (`runtime/plan.json`) instead of a contract, `apply` runs three gates on it before it builds or provisions anything, on both engines: @@ -566,7 +585,7 @@ These write the native engine's execution report. The OpenTofu engine does not w | Option | Default | Description | | --- | --- | --- | -| `--build-id BUILD_ID` | none | Filter build execution to a specific build by ID from the contract's `builds[]`. Needs `--mode amend-and-build` or `--mode replace-and-build`; any other mode is refused with `apply_build_id_requires_build_mode`. When unset and the mode requires builds, every build runs. | +| `--build-id BUILD_ID` | none | Filter build execution to a specific build by ID from the contract's `builds[]`. Needs `--mode amend-and-build` or `--mode replace-and-build`; any other mode is refused with `apply_build_id_requires_build_mode`. When unset and the mode requires builds, every build runs. *(On forge-cli `main`, not yet in a release, [forge-cli #808](https://github.com/Agenticstiger/forge-cli/pull/808).)* An id that matches none of the contract's builds is refused with `apply_build_id_not_found` before anything is applied; see [Build ids](#build-ids). | | `--delay DELAY` | `2` | Seconds between build iterations. | | `--fail-fast` | off | Stop on first failure. | | `--no-output` | off | Suppress build script output. | @@ -602,6 +621,7 @@ Each failure prints the typed event name and an `[ERR_]` slug, and exits | `bundle_env_mismatch` | `--env` differs from the env a bundle was built for. | | `apply_build_id_requires_build_mode` | `--build-id` with a mode that runs no build. | | `apply_build_identifier_invalid` | *(On forge-cli `main`, not yet in a release, [forge-cli #803](https://github.com/Agenticstiger/forge-cli/pull/803).)* A build mode, and an `id` or `builds[].id` the build phase cannot use. Nothing is applied. See [Build ids](#build-ids). | +| `apply_build_id_not_found` | *(On forge-cli `main`, not yet in a release, [forge-cli #808](https://github.com/Agenticstiger/forge-cli/pull/808).)* A build mode, and a `--build-id` that matches no `builds[].id`. The error lists the ids the contract has. Nothing is applied. See [Build ids](#build-ids). | | `apply_mode_data_loss_blocked` | `replace` or `replace-and-build` without `--allow-data-loss`. | | `opentofu_data_loss_gate` | An OpenTofu plan destroys a resource and `--allow-data-loss` is not set. *(On forge-cli `main`, not yet in a release, [forge-cli #793](https://github.com/Agenticstiger/forge-cli/pull/793).)* Also a plan that changes the column types of a Glue table in place. | | `opentofu_plan_failed` | `tofu plan` failed. *(On forge-cli `main`, not yet in a release, [forge-cli #786](https://github.com/Agenticstiger/forge-cli/pull/786).)* A plan that failed on a held state lock suggests `tofu force-unlock `. | diff --git a/docs/upgrading.md b/docs/upgrading.md index d5ca2b0..bd57aec 100644 --- a/docs/upgrading.md +++ b/docs/upgrading.md @@ -633,6 +633,15 @@ These changes are merged and in no release yet. Most fail closed where a contrac stopped with "Unexpected error". Now the run stops first with `apply_build_identifier_invalid`. Rename the id. A renamed `id` gets a new `.fluid/iac//` workdir, and its builds start without their cursors and watermarks. See [Build ids](./cli/apply.md#build-ids). +- **A build mode refuses a `--build-id` that names no build, before anything is applied** + ([#808](https://github.com/Agenticstiger/forge-cli/pull/808)). `fluid apply --mode + amend-and-build --build-id ` (and `replace-and-build`) checks the id against the + contract's `builds[].id` before the apply hooks, `tofu` and any build. Ids match exactly, + case and spaces included. On the OpenTofu engine a mistyped id used to provision the + product, and the run then stopped with `Build not found`. Now it stops first with + `apply_build_id_not_found`, which lists the contract's build ids. The exit code is still + `1`. A Command Center run records the event `apply_build_id_not_found` where it recorded + `build_not_found:`. See [Build ids](./cli/apply.md#build-ids). - **`fluid doctor --strict` and a readable failed apply** ([#786](https://github.com/Agenticstiger/forge-cli/pull/786)). `fluid doctor --strict` exits `1` when the summary says "Action needed", copilot readiness included; the default exit code does not