Skip to content

Rollback#332

Open
spinlock99 wants to merge 4 commits into
labzero:masterfrom
spinlock99:rollback
Open

Rollback#332
spinlock99 wants to merge 4 commits into
labzero:masterfrom
spinlock99:rollback

Conversation

@spinlock99
Copy link
Copy Markdown
Contributor

Description

Implements Rollback Strategy by timestamping releases and keeping a current pointer to the active release.

Fixes #243

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Checklist:

  • Typespecs updated
  • Module documentation updated
  • Tests were added or updated to cover changes
  • Commits have been squashed into a single coherent commit

Licensing/Copyright

By submitting this PR, you agree to the following statement, please read before submission!

I certify that I own, and have sufficient rights to contribute, all source code and
related material intended to be compiled or integrated with the source code for Bootleg
(the "Contribution"). My Contribution is licensed under the MIT License.

NOTE: If you submit a PR and remove the statement above, your PR will be rejected. For your PR to be
considered, it must contain your agreement to license under the MIT license.

Andrew Dixon and others added 4 commits May 27, 2026 13:24
# Bootleg: Timestamped Release Directories (Breaking Change)

## Context

Bootleg currently deploys by unpacking a tarball directly into the workspace root, resulting in a flat `<workspace>/<appname>/` directory that gets overwritten on every deploy. This makes rollback impossible and leaves no deployment history.

This change implements the Capistrano-style pattern proposed in [labzero#243](labzero#243): each deploy unpacks into a timestamped directory under `releases/`, and a `current` symlink points at the active release. This is a **breaking change** — the flat deploy structure is removed entirely with no backward-compat mode.

## Target directory structure on `:app` hosts

```
<workspace>/
├── releases/
│   ├── 20240101120000/   ← previous
│   │   ├── bin/myapp
│   │   ├── lib/
│   │   └── releases/
│   └── 20240115093000/   ← current
│       ├── bin/myapp
│       └── ...
└── current -> releases/20240115093000
```

## Files changed

- `lib/bootleg/tasks/deploy.exs` — `:unpack_release` now extracts into `releases/<ts>/`, symlinks `current`, deletes tarball, optionally prunes via `config :keep_releases, N`
- `lib/bootleg/tasks/start.exs`, `stop.exs`, `restart.exs`, `ping.exs`, `update.exs` — all `bin/<app>` paths changed to `current/bin/<app>`
- `lib/bootleg/tasks/rollback.exs` (new) — re-points `current` at the second-most-recent release and restarts
- `lib/mix/tasks/rollback.ex` (new) — exposes `mix bootleg.rollback`

## New optional config key

```elixir
config :keep_releases, 5   # prune to last N releases after each deploy; omit to keep all
```

## Notes

`--strip-components` was dropped in favour of extract-then-move because BusyBox `tar` (Alpine Linux) silently ignores that flag.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
We timestamp the folder and archive name when we create the tarball from
the elixir build. This lets us not worry so much about passing around
the timestamp to the different parts of deploy that need it and rather
just looking for the newest folder in releases/ when we update the
current/ pointer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Possible enhancement: Create timestamped deploy directories & symlink "current"

1 participant