# Shipping Ghost

Ghost treats `main` as always green and working, so Admin and server changes
must remain compatible without assuming they ship together as we move towards
continuous delivery.

## At a glance

| Track | Current cadence |
| --- | --- |
| Admin (Pro only) | Every commit to `main` after its Admin release-path checks pass |
| Portal and other public apps | When the app changes on `main` |
| Admin + Server (Public Release) | Weekly on Tuesdays |
| Admin + Server (Docker Official Image) | Follows public release after Docker team review |
| Server (Pro only) | Daily rollout on weekdays |

## Admin

Admin on Ghost(Pro) uses continuous delivery. Every commit to `main` publishes a
new Admin build and makes it live after its Admin build and Docker release-path
checks pass.

The public Ghost release contains a Ghost Admin build to keep self-hosted
installs easy to manage.

## Public apps

These public apps are npm packages served through jsDelivr:

- `@tryghost/portal`
- `@tryghost/sodo-search`
- `@tryghost/comments-ui`
- `@tryghost/signup-form`
- `@tryghost/announcement-bar`
- `@tryghost/admin-toolbar`

The full list lives in
[`scripts/public-apps.json`](../../scripts/public-apps.json). When one changes on
`main`, CI publishes a new patch version to npm and clears the jsDelivr cache.
Sites load the latest patch in the major/minor line configured by Ghost, so a
patch can go live without a Ghost release.

A minor or major app release is different. It changes the major/minor version
pinned by Ghost. The new line becomes the default when that change is included
in a public Ghost release and the site upgrades. See the app's README for that
release process.

## Public Ghost releases

An automated workflow releases a new public Ghost version every Tuesday.

A version tag starts the release jobs in
[`ci.yml`](../../.github/workflows/ci.yml). CI:

- builds and tests the Ghost package with Ghost-CLI
- publishes that package to npm
- creates the GitHub release and release notes
- starts the Docker Official Image update

For a normal `ghost install` or `ghost update`, Ghost-CLI downloads the `ghost`
package from npm and checks its published checksum. It does not use the source
ZIP generated by GitHub.

Ghost-CLI also accepts a local `.zip`, `.tgz`, or `.tar.gz` through its
`--archive` option. This is useful for testing a CI build, but it is not the
normal release path.

## Docker Official Image

After the npm package is published:

1. [`TryGhost/docker-library-ghost`](https://github.com/TryGhost/docker-library-ghost)
   updates its Dockerfiles for the new Ghost and Ghost-CLI versions.
2. Automation opens a pull request in
   [`docker-library/official-images`](https://github.com/docker-library/official-images).
3. A Docker Official Images maintainer must approve and merge the pull request.
4. Docker builds and publishes the official `ghost` images on Docker Hub.

The approval must come from the Docker team, not the Ghost team. This means the
Docker image can appear later than the npm and GitHub release.

## Ghost(Pro) Server

In an effort to move continuous delivery beyond Admin, we currently roll out
the latest Ghost server to Ghost(Pro) daily on weekdays.

We're investigating adding a public "nightly" build in the near future.
