# Compose<no value>
// <!-- Required for asciidoctor -->
:toc:
// Set toclevels to be at least your hugo [markup.tableOfContents.endLevel] config key
:toclevels: 4

== Description

The updatecli compose feature allows specifying a list of updatecli policies to enforce.
This is useful when applying the same policies on multiple repositories.

By default, it relies on a file named `updatecli-compose.yaml` in the current directory,
overridable with the `--file` (`-f`) flag, such as in the follow example:

.updatecli-compose.yaml
```
policies:
  - name: Local Updatecli Website Policies
    config:
      - updatecli/updatecli.d/

  - name: Handle Nodejs version in githubaction
    policy: ghcr.io/updatecli/policies/policies/nodejs/githubaction:latest
    values:
      - updatecli/values.d/scm.yaml
      - updatecli/values.d/nodejs.yaml
```

* Running `updatecli compose apply` would enforce the state defined in each of the policies
* Running `updatecli compose diff` would show the targeted state defined in each of the policies
* Running `updatecli compose show` would show the manifest generated by each of the policies

NOTE: `update-compose.yaml` is the deprecated former default filename. Updatecli still picks it up, with a warning, when no `updatecli-compose.yaml` exists.

== Parameters

{{< composeparameters >}}

=== Values precedence

A policy pulled from a registry ships its own values and secrets files.
The compose file can add more, at two levels: the root keys `values`, `valuesinline`, and `secrets`
apply to every policy, while the same keys under an individual policy apply to that policy only.

They are combined rather than replaced, in this order, later winning over earlier:

. values and secrets shipped by the policy itself
. root level `values`, then the policy's own `values`
. root level `secrets`, then the policy's own `secrets`
. root level `valuesinline`, then the policy's own `valuesinline`

The merge is recursive, so two files can contribute different keys to the same nested object,
and only conflicting leaves are overridden.

NOTE: Paths in `values` and `secrets` are resolved relative to the compose file, not to the current working directory.

=== Environment variables

The root keys `environments` and `env_files` set environment variables before the policies are
evaluated, which is how you feed `{{ requiredEnv "..." }}` in a policy without exporting anything in
your shell.

[source,yaml]
----
environments:
  UPDATECLI_GITHUB_OWNER: updatecli

env_files:
  - .env

policies:
  - name: Local policies
    config:
      - updatecli/updatecli.d/
----

The two keys do not behave the same way:

* `environments` sets each variable unconditionally, overriding whatever the shell already exported.
* `env_files` reads https://github.com/joho/godotenv[dotenv] files and **never overrides an existing variable**, which makes it suitable for defaults rather than for forcing a value.

[IMPORTANT]
====
* These variables are set in the Updatecli process itself, so they apply to every policy of the run, not only to the ones declared after them.
* Unlike `values` and `secrets`, `env_files` paths are resolved relative to the current working directory, not to the compose file.
====

=== Splitting a compose file

The root key `include` loads other compose files, whose policies are appended to the run.
Circular includes are detected and skipped, so a file is never loaded twice.

[source,yaml]
----
include:
  - compose/golang.yaml
  - compose/container.yaml
----

Included paths are resolved relative to the file declaring them.

=== Selecting policies

Give a policy an `id` to be able to run a subset of the compose file:

[source,yaml]
----
policies:
  - name: Handle Nodejs version in githubaction
    id: nodejs
    policy: ghcr.io/updatecli/policies/policies/nodejs/githubaction:latest
----

[source,bash]
----
# Only run the policies with these ids
updatecli compose diff --only-policy-ids=nodejs

# Run everything but these ones
updatecli compose diff --ignored-policy-ids=nodejs
----

IMPORTANT: With `--only-policy-ids`, policies without an `id` are skipped, since they cannot be selected.

== Examples

=== Updatecli

The repository **link:https://github.com/updatecli/policies[updatecli/policies]** contains a list of common updatecli policies published on **link:https://github.com/orgs/updatecli/packages?tab=packages&q=policies[GitHub Registry]**.

== Go Further

* To know more about how a policy is built and published, see **link:/docs/core/shareandreuse/[Updatecli policy]**
* To know more about filtering the pipelines inside those policies, see **link:/docs/core/label/[labels]**
