mina-deploy/mina
Blazing fast deployer and server automation tool
Stale — last commit 2y ago
worst of 4 axesnon-standard license (Other); last commit was 2y ago
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓23+ active contributors
- ✓Distributed ownership (top contributor 36% of recent commits)
- ✓Other licensed
Show 4 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Stale — last commit 2y ago
- ⚠Non-standard license (Other) — review terms
What would change the summary?
- →Use as dependency Concerns → Mixed if: clarify license terms
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/mina-deploy/mina)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/mina-deploy/mina on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: mina-deploy/mina
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/mina-deploy/mina shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Stale — last commit 2y ago
- 23+ active contributors
- Distributed ownership (top contributor 36% of recent commits)
- Other licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 2y ago
- ⚠ Non-standard license (Other) — review terms
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live mina-deploy/mina
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/mina-deploy/mina.
What it runs against: a local clone of mina-deploy/mina — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in mina-deploy/mina | Confirms the artifact applies here, not a fork |
| 2 | License is still Other | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 676 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of mina-deploy/mina. If you don't
# have one yet, run these first:
#
# git clone https://github.com/mina-deploy/mina.git
# cd mina
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of mina-deploy/mina and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "mina-deploy/mina(\\.git)?\\b" \\
&& ok "origin remote is mina-deploy/mina" \\
|| miss "origin remote is not mina-deploy/mina (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
&& ok "license is Other" \\
|| miss "license drift — was Other at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "lib/mina.rb" \\
&& ok "lib/mina.rb" \\
|| miss "missing critical file: lib/mina.rb"
test -f "lib/mina/application.rb" \\
&& ok "lib/mina/application.rb" \\
|| miss "missing critical file: lib/mina/application.rb"
test -f "lib/mina/dsl.rb" \\
&& ok "lib/mina/dsl.rb" \\
|| miss "missing critical file: lib/mina/dsl.rb"
test -f "lib/mina/runner.rb" \\
&& ok "lib/mina/runner.rb" \\
|| miss "missing critical file: lib/mina/runner.rb"
test -f "lib/mina/backend/remote.rb" \\
&& ok "lib/mina/backend/remote.rb" \\
|| miss "missing critical file: lib/mina/backend/remote.rb"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 676 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~646d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/mina-deploy/mina"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Mina is a blazing-fast deploy and server automation tool that generates entire Bash deployment procedures as a single script rather than executing commands sequentially over SSH. Unlike Capistrano which opens persistent SSH connections for each command, Mina compiles Ruby DSL definitions into optimized Bash and executes everything in one remote SSH session, dramatically reducing deployment latency. Single-package Ruby gem (mina.gemspec) with lib/mina/ as the core engine. Entry point is bin/mina CLI. Core DSL lives in lib/mina/dsl.rb, command execution in lib/mina/commands.rb, with backend abstraction (lib/mina/backend/) supporting local and remote execution. Bash generation happens via lib/mina/runner/ and lib/mina/application.rb orchestrates the pipeline.
👥Who it's for
DevOps engineers and Ruby developers who deploy Rails applications and need fast, reliable server automation. They want to avoid the overhead of sequential SSH command execution while maintaining an expressive, Ruby-based configuration language (Minafile).
🌱Maturity & risk
Production-ready and actively maintained. Version 1.0.0 is released (see CHANGELOG.md and PRE_1_CHANGELOG.md tracking migration from 0.3.x). The repo has CI/CD via .github/workflows/ci.yml, comprehensive test suite under spec/, and clear documentation in docs/. Sponsored by Infinum with recent active maintenance.
Low risk for established projects already on Rails. Breaking changes exist between pre-0.3 and 1.0.0 (documented in docs/migrating.md), requiring attention if upgrading old deploys. Ruby 2.0.0+ requirement may limit very legacy environments. No obvious single-maintainer risk given Infinum sponsorship.
Active areas of work
The repo appears stable on v1.0.0 with focus on documentation (docs/ directory is comprehensive) and plugin ecosystem (docs/3rd_party_plugins.md). No active breaking development visible in file structure; maintenance appears incremental with CI validation via .github/workflows/ci.yml.
🚀Get running
git clone https://github.com/mina-deploy/mina.git
cd mina
bundle install
bundle exec rake # Run test suite
bundle exec mina init # Initialize a new Minafile in a project
Daily commands:
bundle exec mina --help # Show available commands
bundle exec mina init # Generate config/deploy.rb
bundle exec mina deploy # Run deploy task (defined in Minafile)
bundle exec rspec # Run test suite
🗺️Map of the codebase
lib/mina.rb— Main entry point that initializes the Mina application and DSL, essential for understanding how the tool bootstraps.lib/mina/application.rb— Core Application class orchestrating task execution, configuration loading, and the overall deploy workflow.lib/mina/dsl.rb— Domain-specific language implementation that defines the deploy task syntax users write in their Minafiles.lib/mina/runner.rb— Executes generated Bash scripts either locally or remotely; the heart of Mina's single-SSH-connection deployment model.lib/mina/backend/remote.rb— SSH backend that handles remote command execution on target servers; critical for understanding deployment transport.lib/mina/configuration.rb— Configuration management that loads and validates deploy settings from Minafiles and environment variables.data/deploy.sh.erb— Bash script template that generates the actual deployment script; shows what Mina compiles to under the hood.
🛠️How to make changes
Add a new built-in deployment task
- Define the task function in lib/mina/commands.rb following existing patterns like
deployorsetup(lib/mina/commands.rb) - Use the DSL methods (invoke, run, queue) to compose shell commands within your task (
lib/mina/dsl.rb) - Add unit tests in spec/lib/mina/commands_spec.rb to verify task behavior (
spec/lib/mina/commands_spec.rb) - Document the task in docs/default_plugins.md for user reference (
docs/default_plugins.md)
Create a custom deployment helper
- Add new helper methods to lib/mina/helpers/internal.rb or create a plugin in lib/mina/ (
lib/mina/helpers/internal.rb) - Make the helper available in user Minafiles by extending the DSL context in lib/mina/dsl.rb (
lib/mina/dsl.rb) - Write specs in spec/lib/mina/helpers/ to test your helper functions (
spec/lib/mina/helpers/internal_spec.rb) - Update docs/cookbook.md with usage examples (
docs/cookbook.md)
Extend output formatting or logging
- Modify or extend lib/mina/runner/pretty.rb to customize console output formatting (
lib/mina/runner/pretty.rb) - Update lib/mina/helpers/output.rb for any new output helper functions (
lib/mina/helpers/output.rb) - Add tests in spec/lib/mina/runner/pretty_spec.rb or spec/lib/mina/helpers/output_spec.rb (
spec/lib/mina/runner/pretty_spec.rb)
Add support for a new remote backend
- Create a new backend class in lib/mina/backend/ (e.g., lib/mina/backend/sftp.rb) inheriting from the base pattern (
lib/mina/backend/remote.rb) - Implement command execution methods matching the interface in lib/mina/backend/local.rb (
lib/mina/backend/local.rb) - Register the backend in lib/mina/configuration.rb or lib/mina/application.rb (
lib/mina/configuration.rb) - Write backend tests in spec/lib/mina/backend/ and update e2e tests if needed (
spec/lib/mina/backend/remote_spec.rb)
🔧Why these technologies
- Ruby & Rake — Familiar task DSL for developers; Rake provides the execution framework
- Bash script generation — Enables single SSH session deployment (vs. sequential SSH commands like Capistrano); drastically faster for latency-sensitive operations
- ERB templating (deploy.sh.erb) — Allows dynamic Bash script generation with Ruby variable interpolation while keeping shell logic maintainable
- SSH & Net::SSH — Standard protocol for remote server access; Net::SSH is Ruby's mature SSH client library
- RSpec for testing — Dominant Ruby testing framework; supports unit, integration, and e2e specs
⚖️Trade-offs already made
-
Generate a single Bash script and execute remotely in one SSH session
- Why: Dramatically faster than sequential remote commands (Capistrano approach); reduces latency overhead
- Consequence: Debugging failed deployments is harder (error occurs in middle of compiled script); script compilation adds complexity
-
DSL-based task definition in Ruby instead of imperative scripts
- Why: Cleaner, reusable task syntax; leverage Ruby for logic and conditionals
- Consequence: Learning curve for users unfamiliar with Rake or Ruby DSLs; abstraction overhead when shell interaction is needed
-
Both local and remote backends with transparent switching
- Why: Supports development workflows (local testing) and production deployment (remote)
- Consequence: Additional abstraction layer; must handle behavior differences between local/remote execution
-
No built-in rollback mechanism; relies on deploy.lock and manual intervention
- Why: Keeps tool focused and simple; complex rollback strategies vary by application
- Consequence: Users must implement custom rollback logic; potential for manual errors during incident response
🚫Non-goals (don't propose these)
- Does not manage orchestration across multiple independent servers (single target per deploy)
- Does not provide real-time monitoring or log aggregation
- Does not include built-in secrets management (relies on environment variables and external tools)
- Not suitable for container orchestration (Docker Swarm, Kubernetes); designed for traditional server deployments
- Does not provide UI/dashboard (CLI-only tool)
- Does not handle code version control beyond git clone/push checks
🪤Traps & gotchas
SSH key setup must be correct before deploys work (documentation mentions Net::SSH but not explicit SSH config requirements). ERB template syntax in data/deploy.sh.erb is strict — incorrect variable references silently fail in Bash. Task dependencies in DSL are implicit; circular dependencies can hang silently. Windows support requires lib/mina/windows_patches.rb applied (not always obvious when needed). Pre-1.0.0 Minafile syntax is incompatible — migration docs mandatory for existing users.
🏗️Architecture
💡Concepts to learn
- Bash Script Generation — Mina's core differentiator: converting Ruby DSL to Bash at deploy time rather than executing commands live reduces SSH overhead by 50-80% compared to sequential execution
- Net::SSH Protocol (SSH Session Reuse) — Mina opens a single SSH connection and sends one compiled script vs. multiple sequential SSH calls; understanding this model explains why Mina is faster and informs troubleshooting
- ERB Templating (Embedded Ruby) — data/deploy.sh.erb uses ERB to inject Ruby variables into Bash templates; contributors must understand ERB syntax to modify deployment behavior
- DSL (Domain-Specific Language) — Mina's lib/mina/dsl.rb implements a Ruby DSL allowing users to write deploys in fluent Ruby syntax; understanding DSL design patterns is essential for extending Mina
- Backend Abstraction Pattern — lib/mina/backend/ provides local vs. remote execution strategies via polymorphic backends; allows testing without SSH and supports future alternative transports
- Task Dependency Graph — Mina compiles declared task dependencies (e.g., deploy → setup → link_shared) into a Bash execution sequence; understanding task ordering prevents race conditions and deployment failures
- Idempotency in Deployment Scripts — Bash scripts generated by Mina must be re-runnable safely; this informs how tasks are written (checking file existence before creating, etc.) to enable safe retries
🔗Related repos
capistrano/capistrano— Direct competitor solving same deployment problem but via sequential SSH commands instead of Bash generation; Mina's key differentiationruby/rake— Inspiration for Mina's task DSL design; Mina's DSL mirrors Rake's task syntax but compiles to Bash instead of executing Rubyinfinum/eien— Another Infinum-maintained DevOps tool; likely used alongside Mina in their infrastructure ecosystemansible/ansible— Alternative infrastructure-as-code approach; Mina users sometimes choose between Ansible playbooks and Mina for deployment orchestrationhashicorp/packer— Complementary tool for image building; often paired with Mina-based deploys in CI/CD pipelines to create pre-configured servers
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add integration tests for lib/mina/backend/remote.rb SSH operations
The repo has comprehensive unit tests but spec/lib/mina/backend/remote_spec.rb likely lacks coverage for actual SSH command execution, error handling, and connection failures. Since Mina's core value is generating and executing bash scripts remotely, testing the remote backend thoroughly is critical. This would catch regressions in SSH session handling and command execution reliability.
- [ ] Review existing spec/lib/mina/backend/remote_spec.rb to identify gaps in SSH operation testing
- [ ] Add tests for SSH connection failures and retry logic
- [ ] Add tests for bash script generation and remote execution edge cases
- [ ] Add tests for error handling when remote commands fail
- [ ] Ensure tests cover both successful and error paths in lib/mina/backend/remote.rb
Add GitHub Actions workflow for testing against multiple Ruby versions
The repo mentions 'Mina requires ruby 2.0.0 or greater' in the README, but .github/workflows/ci.yml likely tests only one Ruby version. With a mature project supporting multiple Ruby versions, adding a matrix test across Ruby 2.7, 3.0, 3.1, and 3.2 would catch version-specific compatibility issues early and increase confidence in cross-version support.
- [ ] Review .github/workflows/ci.yml to check current Ruby version coverage
- [ ] Update ci.yml to include matrix strategy for Ruby versions 2.7, 3.0, 3.1, 3.2
- [ ] Ensure spec/e2e/e2e_spec.rb runs against all matrix versions
- [ ] Document the minimum supported Ruby version clearly in Readme.md
Add unit tests for lib/mina/dsl.rb DSL parsing and command registration
DSL files are core to Mina's functionality (lib/mina/dsl.rb and spec/configs/dsl.rb exist), but spec/lib/mina/dsl_spec.rb may lack comprehensive coverage of task definition, hooks, and variable scoping. Testing the DSL thoroughly ensures users' deploy.rb files are parsed correctly and edge cases like task conflicts, missing dependencies, and hook ordering are handled properly.
- [ ] Review spec/lib/mina/dsl_spec.rb to identify missing test cases
- [ ] Add tests for task definition and invocation order
- [ ] Add tests for hook execution (before/after deploy hooks)
- [ ] Add tests for variable scoping and environment configuration
- [ ] Add tests for error handling when tasks reference undefined variables or missing tasks
🌿Good first issues
- Add integration tests for lib/mina/backend/remote.rb with mocked SSH to verify actual deploy.sh.erb script output against known good Bash syntax (currently no integration test coverage visible for remote execution path)
- Extend docs/cookbook.md with a 'Rollback strategies' section documenting the rollback task in lib/mina/commands.rb with real-world examples (docs exist but cookbook is thin on edge cases)
- Add RSpec test coverage for lib/mina/dsl.rb task registration and variable scoping edge cases (task override behavior, nested task calls) — existing spec/configs/default.rb is minimal
⭐Top contributors
Click to expand
Top contributors
- @d4be4st — 36 commits
- @lovro-bikic — 33 commits
- @gabskoro — 7 commits
- @coezbek — 2 commits
- [@Nikola Buhinicek](https://github.com/Nikola Buhinicek) — 2 commits
📝Recent commits
Click to expand
Recent commits
dc9deda— Update changelog (lovro-bikic)bb656d7— Bump version to 1.2.5 (lovro-bikic)dccf56b— Revert "Deprecate version manager tasks (#709)" (#724) (lovro-bikic)01f2056— Revert "Support Rails 6 asset recompilation through webpacker" (#723) (lovro-bikic)2e87ff5— Update CI: Add Ruby 3.2 and update GA runners (#722) (lovro-bikic)f638fad— Remove :bundle_options from bundle clean (#710) (lovro-bikic)a387720— Deprecate version manager tasks (#709) (lovro-bikic)efc7c9f— Fixsshtask escaping (#708) (lovro-bikic)d12958f— Refactor CLI options (#707) (lovro-bikic)a23c123— Print correct values indebug_configuration_variablestask (#706) (lovro-bikic)
🔒Security observations
Failed to generate security analysis.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.