Giter Club home page Giter Club logo

branch-deploy's Introduction

branch-deploy

This software is under active development. This is not working software.

For more information, see the initial roadmap.

Setup

$ script/bootstrap

Running

$ bd --help
Usage: bd [options]
    -r, --repo REPOSITORY            Repository passed to 'git clone' command on deployment host [REQUIRED]
    -b, --branch BRANCH              Branch name to deploy [REQUIRED]
    -h, --host HOSTNAME              Target host for remote deployment [REQUIRED, or --local]
    -l, --local                      Deploy to the local host (default: false) [REQUIRED, or --host]
    -p, --path PATH                  Deployment path on target host [REQUIRED]
    -d, --diff                       Return diff output for proposed changes, do not deploy (default: true)
    -c, --confirm                    Confirm deployment -- actually update files (default: false)
    -s, --ssh-options OPTIONS        Flags passed to the 'ssh' command for remote deployment (default: "")
    -t, --temp-path                  Base path for tempdir creation on deployment host (default: OS default)
    -v, --verbose                    Run verbosely (default: false)
    -h, --help                       Prints this help

Testing

$ script/test

Run options: --seed 27657

# Running:

.

Finished in 0.000601s, 1663.8931 runs/s, 1663.8931 assertions/s.

1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

or:

$ bundle exec rake

Run options: --seed 63598

# Running:

.

Finished in 0.000914s, 1094.0919 runs/s, 1094.0919 assertions/s.
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

To view rake test targets:

rake spec           # Run the test suite
rake spec:cmd       # Print out the test command
rake spec:isolated  # Show which test files fail when run in isolation
rake spec:slow      # Show bottom 25 tests wrt time

This project uses minitest.

Linting

This project uses rubocop.

$ bundle exec rubocop

Inspecting 4 files
....

4 files inspected, no offenses detected

branch-deploy's People

Contributors

rick avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

branch-deploy's Issues

Initial roadmap

image

Goal

We (especially @jameswhite and I) have need of an efficient, (dependency-) lightweight single-purpose tool to facilitate "branch deploys", and "branch diffs" for continuing to develop "on-system" software.

This differs from the various ways and tools to deploy (micro-)services and web apps to cloud platforms, kubernetes, etc., for which there are many CI/CD tools and processes.

"On-system?"

By "on-system" software I mean that we are often managing the operating-system level files on a host machine. For instance, files in /etc, configurations of things like LDAP servers, Nagios monitoring, TFTP/PXE configurations, etc.

"Host?"

By "host" we mean a computer, which could be bare metal, a virtual machine (for instance in a VMWare instantiation), a container, a remote cloud-hosted instance. We expect the host to have a running OS and kernel, most often running Linux, but configuration may be minimal.

"source host?", "target host?"

In the timeline below we use these terms to refer to how this deployment tool operates. The "source host" is either a CI instance or some other host which is initiating a deployment, which triggers a branch deployment and/or branch diff onto a "target host". The "target host" is the host where our changes are being deployed (or proposed).

"bd?"

The working name for the command-line tool which is invoked to do branch deployments is bd. This could change depending on whims.

"branch deploys?", "branch diffs?"

[Old man voice:] Back when we worked at GitHub, we deployed software (web applications, supporting tooling, host configurations, eventually network configurations, etc.) using a specific process:

  • Develop changes via Pull Request on a new git branch
  • As changes are pushed to GitHub, CI runs to validate the changes
  • When changes need testing, "branch deploy" them (deploy that git branch of code to either a "branch lab" staging environment, or, eventually) to the production host(s) in question
  • If this deployment proves workable (via various testing and telemetry means) then the Pull Request is merged, and the deployment becomes the new production "mainline" deployment

This is often colloquially referred to as the "GitHub Flow", especially if these operations are undertaken via ChatOps.

Over time, for changes which were less "web application software" and more likely to be systems level software (OS configurations, authorization configurations, network changes), the "branch deploy" phase was often preceded by:

  • Report on the proposed changes, on real hosts, for this branch. This would take the form of a diff, hence "branch diff".

This process, taken together with the technique of separating the deployment and setup of a systems level tool (LDAP, puppet, nagios, vault, or systems such as Entitlements), from the data contents of that tool -- each of which can have its own branch deployment lifecycle -- is sometimes colloquially called the "KP Flow", after Kevin Paulisse who refined and spread this pattern during his time at GitHub.

Development constraints

  • The source host needs to support the language environment (ruby in this case) for the bd command-line tool.
  • The target host for a deployment needs a modern-ish shell (bash, zsh, dash, etc.) to run the deployment commands; git to clone a repository, andrsync to do tree diffing and deployment. It does not need to support the (ruby) language environment.
  • We can use whatever tools and libraries to test and develop, but the software that actually runs on the source host to trigger deployments should use the ruby standard library and nothing else.
  • Testing should be full integration testing if at all possible. That is, no unit testing; definitely no mocking/stubbing tests. We should be able to use containerization to support fully sandbox real deployments during testing.
  • It is not uncommon for configurations for multiple hosts to be managed from a single repository, so support specifying a path into the repository to act as a base path for the files deployed for a specific host.
  • One of the prime targets for system management is the /etc path, and typically there are specific subsets of files being specifically managed, while other files are not under management. This points to being able to specify inclusion paths for managed files, probably with a configuration file available in the repository.
  • I did something like this before, over a decade ago, but experience, platforms, tools, taste, etc., have all evolved. One of the same constraints applies: deployments should be absurdly fast. This probably means that we build a single shell command to handle the entire deployment and send it in one shot.

Timeline

  • get basic development tooling in place
  • write a README for the CLI bd tool usage
  • BDD test-drive the options processing for the CLI tool
  • get container-sandboxed local CI working
  • get container-sandboxed GitHub Actions CI working
  • make bare git repositories to use as fixtures in deployment testing
    • make a place for the bare git repos (spec/repo-fixtures?)
    • make a place for scripts that can build those repositories (spec/repo-builders)
    • make a script that can read all repo-builder scripts
      • foreach name:
        • create a git repo
        • run the builder script against that git repo
        • make sure there is an empty spec/repo-fixtures/ path
        • clone --bare into that repo-fixtures path
  • test drive deployment
    • use bd to deploy a known repo configuration to the target
    • use bd to deploy a branch to the same target
    • ... verify the contents of the target path
      • every managed file from the repo should be present
      • every non-managed file should still be present
      • every managed file not in the repo should be absent
  • do similar for diff deployments
    • verify diff as a list of files added, changed, or removed
    • verify diff as line-level file changes
  • tests for configuration for managed files
  • tests for ssh options
  • tests for local deployments
  • tests for varied in-repo paths
  • tests for varied target paths
  • tests for varied config file paths
  • add support for running hook scripts before and after actually deploying files
    • pre-deploy hook script could run from repo
    • pre-deploy hook script could run from an absolute path
    • post-deploy script runs from an absolute path
  • update main README with this information, and usage information
  • create a rubygem for this and publish it, as the primary way this is used
    • review the libs used by bin/bd and cut any requires that would pollute the gem dependency

This looks cool! โœจ

๐Ÿ‘‹ Hey @rick!

I stumbled across this today and read through your roadmap. I think this project looks really cool and would pair nicely with github/branch-deploy (of the same name ๐Ÿ˜‚).

I do the following all the time in my personal projects, and a few open source projects that I maintain:

  1. Trigger a branch deployment on a PR via a comment .deploy (through github/branch-deploy)
  2. Do a remote deployment by SSHing into a VM and then calling script/deploy on the remote server running an app
  3. ๐Ÿš€

Looking at this project, it looks like it would be a lot better and more robust to use bd rather than a what I'm currently doing which is poorly crafted shell scripts that work(ish).

You might also find this project interesting -> runwaylab/runway. Its an experimental side project that I tossed together to allow branch-deployments to be "completed" by a deployment controller on my homelab so I can still get all the branch-deploy goodies without having to expose a webhook server on my home network.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.