# Release notes for Ambient CI

This file summarizes the user-visible changes to `ambient-ci`
between releases.

## Version 0.16.0, released 2026-06-30

This is brown paper bag release. The previous release completely broke
post-plan actions. They are fixed in this release. This time, I actually
made sure the new version works at least for some of my personal projects
and web sites. Any remaining problems are expected to not be so glaringly,
spectacularly obvious as they were in the previous release.

* The the `rsync` target value computed from a base and a map (see
  `rsync_target_base` and `rsync_target_map` in the configuration) is now
  actually passed in to the `rsync` actions.

* The path to the artifacts directory, or its subdirectory, is now computed
  correctly.

* The `rsync` and `rsync2` actions now log a message if they do nothing,
  because the configuration doesn't set `rsync_target`. In addition, there
  are now log messages when `rsync` is started and when it ends, to make
  the run log easier to follow when troubleshooting.

* Files with secrets, see `secrets` in the Ambient configuration, are now
  copied to the post-plan VM with a 0600 mode: they're readable by owner,
  but nobody else. This enables SSH to actually use them.

* The `rsync` command now runs SSH with the `-v` options to make
  troubleshooting easier.

* The `dput` action now uses `/ci/secrets/dput.cf` as the configuration file.

* The ambient plan --runnable` command now outputs runnable plans derived from
  pre- and post-plans as well as the main plan.

* The HTML run log CSS now makes `argv` entries legible.

## Version 0.15.0, released 2026-06-30

It has been three months since the previous release, but work has not stopped.
Much work has been outside the Ambient repository, however.

### Big important world-shattering changes

* The pre-plan and post-plan are now executed in their own virtual machines,
  which are exactly like the plan VM, but with network access. The motivation
  for this is to add a layer of isolation around pre- and post-plan action
  so that the impact of them misbehaving is more limited. Previously, those
  actions ran directly on the host and could do anything the user running
  Ambient could do. With the new VMs, the actions can only use the configured
  amount of RAM, CPU, and disk space, and can't access files that aren't
  explicitly imported into the VM, such as SSH keys.

  As a consequence, it will be a little less nerve-racking to consider new
  actions for Ambient.

  Any CI project with post-plan actions that need SSH keys will need to
  configure Ambient to copy them to the post-plan VM. See user guide for the
  new `secrets` configuration field.

* The runnable plan generated by Ambient no longer automatically configures
  Git in the VM. The new action `git_config` does that instead. This means
  the VM no longer needs to have `git` installed.

### Breaking changes

* The `debian` and `rsync` directories in `/ci/artifacts` are now created
  automatically. Projects that have been doing it manually may need to be
  adjusted. (`mkdir -p /ci/artifacts/rsync` would be a workaround: the `-p`
  option means an existing directory is OK.)

### Other changes

* Yorgos Saslis fixed the crate name in installation instructions.

* The `deb_get` action now tries several implementations of the Stateless
  OpenPGP CLI interface.

* The configuration fields `rsync_target_base` and `rsync_target_Map` are now
  explained in the user guide.

* A start of an architecture document has been added.

* If the `tar_extract` or `tar_create` actions fail, because the system `tar`
  command failed, the error message now includes the `stderr` output of `tar`.
  This turns out to be useful when troubleshooting problems.

* The maximum size of dependencies can now be configured per project or
  globally.

* The `README.md` file now has a hint on how to test changes to HTML run log
  generation.

* Various Rust dependencies have been updated. Various minor bugs of the typo
  variety have been fixed.


## Version 0.14.0, released 2026-03-30

* Add three pre-plan actions for downloading dependencies: `deb_get`,
  `npm_get`, and `rustup`. In addition add a plan action `deb_install` to
  install `deb` packages downloaded with `deb_get`. These are documented in
  the user guide:

  - [`deb_get`](https://doc.liw.fi/ambient-ci/userguide.html#deb_get)
  - [`rustup`](https://doc.liw.fi/ambient-ci/userguide.html#rustup)
  - [`npm_get`](https://doc.liw.fi/ambient-ci/userguide.html#npm_get)
  - [`deb_install`](https://doc.liw.fi/ambient-ci/userguide.html#deb_install)

  The pre-plan actions download `deb` or `npm` packages or Rust toolchains.
  The `deb_install` action installs the downloaded `deb` packages in the VM.
  The toolchains are available in the VM without installation.

  The downloaded `npm` packages need to be installed in the VM with a command
  such as `npm install --offline=true /ci/deps/npm/node_modules/*.tgz`. Lars
  did not provide an action for this, due to being unfamiliar with the `npm`
  tool and ecosystem. An action can be added later once the concept has proven
  itself.

  These are very raw versions of the actions and are likely inadequate. Please
  try them, report problems, and help fix them. Both `npm_get` and `deb_get`
  work for at least simple cases.

  The purpose of these changes it to enable use of non-Rust dependencies and
  generic cloud images. This is an important step towards making Ambient more
  useful to more kinds of software projects.

* In addition, add a new field `envs` to the runnable plan. This is necessary
  to allow pre-plan actions to set environment variables for the actual
  plan. This enables the `rustup` action to make the downloaded Rust versions
  available without the plan having to set anything up.

  This is a breaking change: `ambient` and `ambient-execute-plan` have to
  both understand the new field. So do the `radicle-ci-ambient` adapter and
  `rad-ci`, which will be updated momentarily.

* The `README` now has some instructions for adding more pre-plan actions for
  downloading dependencies.

## Version 0.13.1, released 2026-03-06

* A bug that caused a panic in how the sequence of run log messages is parsed
  to create synthetic log messages has been fixed.


## Version 0.13.0, released 2026-03-04

Other changes:

* The HTML run log has been improved in various ways.

  - Custom action output is included.
  - Log messages say which part of a CI run they come from.
  - The log page is also divided into sections, based on log message
    source.
  - The HTML log uses synthesized log message to hide repetitive
    steps like "prepare to create directory" followed by "successfully
    created directory". The user now only sees "created directory" by
    default, but can click that open to see all the details.
    As part of this change, the library part for non-synthetic log messages
    is gone.
  - The raw JSON log messages are included in the HTML log, just in case
    they are helpful some day.
  - The VM console log is included in the HTML log to satisfy curious
    people.
  - Log messages and sections have HTML element IDs to allow hyper-
    to them.

* The HTML log now passes the W3C HTML validator.

* The virtual machine console log is captured in the project state
  directory and HTML run log. In the Ambient crate library part, the
  `ambient_ci::qemu::QemuBuilder` now requires setting the path to the console
  log.

* Ambient now has a lint for plan having a `deb` action and post-plan having
  a `dput2` action or `deb2` and `dput`. The version of the actions are
  incompatible: they put the built packages in different directories. The lint
  catches this when a CI run starts, making the problem evident quickly.

* There is also a lint for `shell` actions referring to the old name for the
  workspace, `/workspace`, instead of the new one, `/ci`. The old name will
  work until further notice, but the lint is there to nudge people to switch
  so that some day the old name can be retired safely.

* The Debian packaging now depends on `shellcheck`, for the linting Ambient
  does for `shell` actions.

* The main error type is now called `AmbientError`, renamed from
  `AmbientDriverError`. The old name referred to an old name for Ambient.


## Version 0.12.0, released 2026-02-05

New feature:

* Ambient (`ambient run`) now produces run logs in JSON Lines format (one
  JSON object per line of output). This can be turned into HTML pages using
  `ambient log --format=html`. The HTML page is supposed to easier to navigate
  than tens to thousands of kilobytes of unstructured text. It is expected that
  the HTML logs can still be improved. They are included in a release so that
  the Ambient developers can get feedback on how to improve them.

  The parts where things fail are colored pink in the HTML log. Advice on
  better colors and other ways to distinguish is most welcome.

  To see the new logs, see <https://callisto.liw.fi/> after this release has
  been deployed there. That should happen within an hour or two after it's
  been uploaded to `crates.io`.

  Old run logs (`run.log` in the project state directory) are no longer
  understood by this version of Ambient.

Changed features:

* The `deb` and `deb2` actions log the package directory they create or that
  it already exists. This helps debugging via CI run logs.

Bug fixes:

* In the `deb2` action, if the `/ci/artifacts/debian` directory doesn't exist,
  create it. Although the `deb` and `deb2` actions share code, this doesn't
  change anything for `deb`, as it puts the built package in `/ci/artifacts`,
  which always exists.

## Version 0.11.1, released 2026-01-14

Bug fix:

* Always pass UEFI OVMF firmware file to QEMU, not just when UEFI support
  is on. The change for optional UEFI support in 0.11.0 broke some uses of
  Ambient. This change restores functionaliy at least for my own uses.

## Version 0.11.0, released 2025-12-20

There are more changes than usual in an Ambient release, but they should not
be scary.

### Breaking changes

* The Rust Cargo related actions now use the `cargo-target` subdirectory in
  the workspace cache directory (`/ci/cache/cargo-target`). This is invisible
  to all common uses of Rust in Ambient projects, but allows dividing the
  cache between different kinds of use in the future. This does mean that
  existing caches become obsolete and should be deleted. That makes this
  technically a breaking change.

* Ambient now checks for common problems when it loads the projects file.
  This is know as "the linter". Currently it checks that an `rsync` target
  has been configured if an `rsync` or `rsync2` action is used, that each file
  downloaded by a `http_get` action has a unique filename, and that all shell
  script snippets in `shell` actions are OK according to the `shellcheck`
  program.

  Linting can be prevented by setting `lint` to `false` in the configuration.
  This may be necessary if, say, one of the checks is wrong.

  This is a breaking change because most shell script snippets will be found
  wanting.

* The pre- and post-plan now only allow actions that are actually meant for
  them. Previously both allowed the same set of actions. However, actions like
  `cargo_fetch` don't really make sense for post-plan. Now the separation is
  more strict.

  This is technically a breaking change, but hopefully doesn't actually break
  anything for anyone. If you have a legitimate use for a pre- or post-plan
  action that is now not allowed, let us know.

### Problems fixed

* Some portability fixes for NixOS by invoking the Bash shell by name instead
  of path. NixOS does not put Bash at `/bin/bash`, so using a full path
  doesn't work reliably. Using the name should work anywhere.

* Ambient now checks, when loading the projects file, that the source location
  for a project is a directory (following symlinks) and gives an error if it
  is not. This means the problem is found when Ambient starts and not much
  later when it starts running CI for a specific project. If there are many
  projects, that might be hours later.

### New features added

* The workspace in the VM is now `/ci`. The old name `/workspace` will work
  indefinitely. The new name is shorter and arguably clearer. The workspace
  is set up by `ambient-execute-plan` and so this change does not affect any
  VM images.

* There is now a user guide for Ambient, published by CI at
  <https://doc.liw.fi/ambient-ci/userguide.html> and included in the `deb`
  package at `/usr/share/doc/ambient-ci/userguide.html`. The user guide
  contains a description of each action that a project CI plan can use. The
  guide is woefully lacking, but it's easier to add things to something that
  exists than starting from an empty directory.

* The Ambient subplot document is formatted and published at
  <https://doc.liw.fi/ambient-ci/ambient.html>. It may be useful for checking
  how a specific aspect of Ambient is used. The subplot is the test suite
  that verifies most aspects. That means it's continually run and does not
  easily get out of date.

* New action `setenv` allows setting environment variables for later actions.
  Using the `shell` action does not work for this, because each shell forgets
  any changes to its environment variables when it terminates.

  ~~~yaml
  - action: setenv
    set:
      foo: bar
  ~~~

* New plan action `deb2` and post-plan actions `dput2` and `rsync2` use
  subdirectories `debian` and `rsync` in the artifacts directory. This
  means if a project both builds documentation and a `deb` package, they
  don't get mixed into the same directory. Instead, documentation goes into
  `/ci/artifacts/rsync` and the package into `/ci/artifacts/debian`.

  The old actions `deb`, `dput`, and `rsync` continue to work as before and
  use the whole artifacts directory. The new actions were added to avoid
  changing the existing actions in an incompatible, breaking way. The old
  actions are not deprecated.

  The runnable plan versions of the old actions have changed. The plan and
  post-plan actions result in the same runnable plan action. Changes to
  runnable actions are not currently considered breaking changes in Ambient.

* In the VM, the `git` command is now configured by default to have "Ambient
  CI" as the name for the user and "`ambient@example.com`" as the email
  address. This removes the need for each project to do that in their CI plan
  just to use `git`.

* New subcommand `ambient state` lists the projects in the Ambient state
  directory (configuration field `state`) and the sizes of the files and
  subdirectories they contain. The output looks like this:

  ~~~json
  {
    "projects": {
      "dummy": {
        "latest_commit": "09d6a5d81a5001bf210df2bf80e871e3731f6e9f",
        "run_log": 21370,
        "dependencies": 472923464,
        "cache": 2074946410,
        "artifacts": 4096
      },
    },
    "project_count": 6
  }
  ~~~

* The `ambient qemu` subcommand has been added to execute a runnable plan in
  a virtual machine, with or without networking. This is primarily a utility
  command to help develop Ambient by making it easier to experiment.

* The configuration file now allows enabling UEFI use for an image. The `run`
  and `qemu` subcommands additionally have a `--uefi` option for that.

* The `ambient qemu --persist` options allows creating a variant of an image.
  This can be used, for example, to change a generic cloud image from Debian
  or Arch Linux to boot fast even if the VM has no network access. Together
  with the optional UEFI support this paves way for using generic images
  instead of custom images for Ambient. That, in turn, should enable Ambient
  users to run CI under other operationg systems in the VM. However, Ambient
  needs further changes to make this convenient.

* Ambient now gives an error message if a virtual drives is too big. The
  virtual drives are created before the virtual machine starts. Previously,
  there was no helpful error message, only an "assert" error that only makes
  sense to Ambient developers.

* The exported parts of the Ambient library part now all have documentation.
  This makes the library usable from other programs, but more importantly,
  makes it harder for Lars to forget what a type or method is for. Many typo
  fixes and other changes were made to exported names.

  Note that Ambient is probably not very useful to use as a library. If you
  use it that way, or would like to, please be in touch and let us know so can
  try to avoid breaking it for you.


## Version 0.10.0, released 2025-11-24

* The `cargo_fetch` pre-plan action is now safer and more secure. The
  action at its core run `cargo fetch` in the source tree. It turns out
  `cargo` lets the source tree configure commands to run instead of
  `rustc` etc, which means the source tree can run any program. This is
  not acceptable. Instead, the action now pares down the source tree
  to `Cargo.toml`, `Cargo.lock`, and `*.rs` files, which is enough to let
  `cargo fetch` work, but removes any files that can be used to override
  things for `cargo`. (`cargo fetch` does not build or run `build.rs`.)

* The `spawn` action has been dropped. Use the `shell` action instead.

* The run time configuration is now only logged when it's computed,
  dropping spurious extra log spam.

* An internal change, not visible to users, is that all action implementations
  are now in their own module, `action_impl`. This makes the codebase somewhat
  clearer and more tidy, which will make maintenance of the actions easier in
  the future.


## Version 0.9.0, released 2025-11-13

* The `http_get` action now uses the `If-Modified-Since` HTTP request
  header correctly. This means it won't re-download a file unless it has
  changed on the server.

* Actions in `plan` now have the `HOME` environment variable set. It set by
  the `ambient-execute-plan` when it executes the actions.

## Version 0.8.0, released 2025-10-01

Breaking changes:

* It is now an error for the runnable plan given to `ambient-execute-plan`to
  have unknown fields. This is technically a breaking change, but should not
  actually break any valid use. The only people affected should be those who
  write or generate their runnable plans without `ambient`. The change was made
  to make problems in the runnable plan more explicit.

Brown paper bag bug fixes:

* `ambient` now fails a run if an action in the VM fails. This was always
  meant to be the case, but broke at some point. There is now an explicit
  acceptance criterion to verify this doesn't break again.

New features:

* The option `ambient plan --yaml` was added to output the plan, as loaded
  into memory by `ambient`, in the YAML format. The default is JSON, added
  for the sake of testing. The YAML output should help those who want to have
  something they can rely on being at least syntactically correct.

* The option `ambient plan --runnable` was added to generate and output the
  runnable plan for a project. This should help those who want to play with
  `ambient-execute-plan` outside a VM.

* The action `cargo_deny` to run `cargo deny` has been added.


## Version 0.7.0, released 2025-09-19

* All actions get the environment variables to use the Rust toolchain.
  This change will eventually make it easier to have actions that set
  environment variables for later actions, but that has not yet been
  implemented.

* `ambient-execute-plan` now logs its own version at startup. This is
  helpful for troubleshooting why fixes to it don't work in tests. (It's
  usually because the tests use the wrong version of the program.)

## Version 0.6.0, released 2025-09-19

* The `cargo_fetch` actions now runs with the `--locked` option only
  if the `Cargo.lock` file exists.

* All actions that run `cargo` or `rustc` log their versions.

* New pre-plan action `http_get` allows downloading files into the
  dependencies before the VM start.

* New action `cargo_doc` verifies that Rust documentation comments can
  be formatted.

* Run log now contains stdout and stderr of any programs run by
  actions. This especially affects `tar_extract` and `tar_create`
  actions and will make it visible when creating a tar archive from,
  say, the cache directory fails due to a full disk.

* License is now clarified to be GNU GPL version 3 or later.
  Previously it was that and AGPL version 3.

## Version 0.5.2, released 2025-09-10

* If QEMU fails, log its stderr.

## Version 0.5.1, released 2025-08-12

* This release fixes a bug in the new `custom` action. The action is
  now run in the source directory.

## Version 0.5.0, released 2025-08-12

* A new, experimental action `custom` has been added. It can be used
  in `plan`, so that it is only available in the VM. The action
  executes a program in the `.ambient` directory at the root of the
  source tree. This is a first step towards user-provided action
  implementations.

## Version 0.4.0, released 2025-07-20

Breaking changes:

* Ambient now uses `xorriso` instead of `genisoimage` to generate an
  ISO file as a `cloud-init` local data storage. This is a breaking
  changes, as `genisoimage` is not used even if available. Thank you
  to Tobias Hunger.

Other changes:

* The way Ambient invokes QEMU is now more configurable, thanks to
  Tobias Hunger. The configuration file now has a field `qemu` with
  fields``cpu`, `memory`, `kvm_binary`, `ovmf_vars_file`, and
  `ovmf_code_file` can be set. Of these, `cpus` and `memory` were
  possible to set at the top level of the configuration file from
  before. They still can be, to avoid breaking backwards
  compatibility. The new fields take precedence.
  
* QEMU is now invoked with strict boot mode, system UUID, hostname,
  and other improved settings, thanks to Tobias Hunger.

* The `target` configuration file setting is now known as
  `rsync_target`, for clarity. Likewise the option `--target` is now
  known as `--rsync-target`. The old names also work.

* There is now a new configuration file setting `rsync_target_base`,
  to which the project name is joined, if `rsync_target` is not set.
  This allows the same base target to be used for a family of projects
  that publish their artifacts to sibling directories.
  
  There is also a setting `rsync_target_map` to allow setting the
  rsync target URL for each project separately. This is for
  convenience.
  
* The `tmpdir` setting now defaults to `TMPDIR` in the environment, if
  that is set.

* The `--config` option can be used many times, to allow many
  configuration files to be loaded. This is for flexibility.

* The `--no-config` option prevents the default configuration from
  being loaded.

* The `--version` outputs a version number, which now includes the Git
  commit of the sources. This is to enable better remote support.

* There is some preliminary sketches of an `ambient image` group of
  subcommands for managing a library of virtual machine images. This
  is not really usable yet, however, because Lars Wirzenius wasn't
  able to dedicate enough time to complete this work. It was merged,
  and thus included in this release, so that it doesn't bit rot in an
  abandoned branch.

* The `tar_extract` action now lists the files that are extracted. The
  action can only be used in the plan, not in the pre- or post-plans.

* The `ambient plan` command outputs the pre-, post-, and actual plans
  for a CI run for a project. This is meant to provide visibility as
  to what happens.

* There are various improvements to what gets logged, but log files
  are still mostly only useful to those familiar with the source code.

## Version 0.3.0, released 2025-04-17

* The error message for when running `qemu-img` fails now mentions
  `qemu-img`. Previously the error was only "File not found", which is
  not very useful to the user.

* The error message for being unable to read a log file now mentions
  the name of the log file. This, too, is meant to be useful to users,
  when there's a problem.

* The result of `ambient-execute-plan` running an action in the
  virtual machine is now shown explicitly. Previously the success of
  executing an action was not logged, it was implicit in that the run
  didn't end in failure.

* The `cargo_fetch`, `cargo_clippy`, and `cargo_build` actions now
  don't use the `-vvv` option, which tells Cargo to be very, very,
  very verbose. This is to make run logs be of a tolerable size and
  not hide problems under a mountain of text. In the long term,
  Ambient should produce logs where that kind of verbosity can be
  controlled at reading time.

* The default log level for `ambient` is not `info`, previously
  `warn`. This makes running the command a little more verbose. The
  log level can be controlled with the `AMBIENT_LOG` environment
  variable.

* When `ambient` makes a copy of the OVMF file (part of the UEFI
  implementation for virtual machines) it now gives the user who runs
  `ambeint` write permission to the copy.

* The `ambient image import` command now has a progress bar. Importing
  computes a SHA256 checksum, which can take a while, and the progress
  bar keeps the user amused.

* The `README.md` file now mentions how to build the code and run the
  tests (TL;DR: `make`), and what build time dependencies are needed
  for this.


## Version 0.2.0, released 2025-03-17

There are no big changes, except the name change. The purpose of this
release is to update the Rust crate with the new name.

* Installation documentation are now included in the file
  `INSTALL.md`. They aren't verified automatically, but did work when
  tested manually at the time they were written.

* The binary has been renamed to `ambient`. The Rust crate has been
  renamed to `ambient-ci`. The primary source code repository has been
  moved to Radicle (repository id `rad:zwPaQSTBX8hktn22F6tHAZSFH2Fh`),
  but the old Codeberg location will continue to work.

## Version 0.1.0, released 2025-01-09

The first release. This was released under the name `ambient-driver`,
because Lars didn't think clearly.
