{"id":13756065,"url":"https://github.com/AnalogJ/capsulecd","last_synced_at":"2025-05-10T03:30:44.333Z","repository":{"id":36341483,"uuid":"40646209","full_name":"AnalogJ/capsulecd","owner":"AnalogJ","description":"Continuous Delivery for automating package releases (npm, cookbooks, gems, pip, jars, etc)","archived":true,"fork":false,"pushed_at":"2021-08-09T04:21:31.000Z","size":30181,"stargazers_count":97,"open_issues_count":36,"forks_count":5,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-22T17:00:45.620Z","etag":null,"topics":["chef","chef-cookbook","continuous-integration","docker","nodejs","npm","packaging","pypi","python","ruby","rubygems","supermarket"],"latest_commit_sha":null,"homepage":"https://analogj.github.io/capsulecd-slides/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AnalogJ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-13T07:57:23.000Z","updated_at":"2024-11-30T05:45:38.000Z","dependencies_parsed_at":"2022-09-13T03:02:29.565Z","dependency_job_id":null,"html_url":"https://github.com/AnalogJ/capsulecd","commit_stats":null,"previous_names":[],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnalogJ%2Fcapsulecd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnalogJ%2Fcapsulecd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnalogJ%2Fcapsulecd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnalogJ%2Fcapsulecd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AnalogJ","download_url":"https://codeload.github.com/AnalogJ/capsulecd/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253358069,"owners_count":21895967,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chef","chef-cookbook","continuous-integration","docker","nodejs","npm","packaging","pypi","python","ruby","rubygems","supermarket"],"created_at":"2024-08-03T11:00:35.339Z","updated_at":"2025-05-10T03:30:43.989Z","avatar_url":"https://github.com/AnalogJ.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# CapsuleCD\n\n\n\n\u003e WARNING: CAPSULECD IS DEPRECATED\n\u003e It's been replaced by Packagr, a series of small composable tools, with all the same functionality: https://github.com/PackagrIO/docs\n\n\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/AnalogJ/capsulecd\"\u003e\n  \u003cimg width=\"300\" alt=\"portfolio_view\" src=\"https://cdn.rawgit.com/AnalogJ/capsulecd/master/logo.svg\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\n[![Circle CI](https://img.shields.io/circleci/project/github/AnalogJ/capsulecd.svg?style=flat-square)](https://circleci.com/gh/AnalogJ/capsulecd)\n[![Coverage Status](https://img.shields.io/codecov/c/github/AnalogJ/capsulecd.svg?style=flat-square)](https://codecov.io/gh/AnalogJ/capsulecd)\n[![GitHub license](https://img.shields.io/github/license/AnalogJ/capsulecd.svg?style=flat-square)](https://github.com/AnalogJ/capsulecd/blob/master/LICENSE)\n[![Godoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/analogj/capsulecd)\n[![Go Report Card](https://goreportcard.com/badge/github.com/AnalogJ/capsulecd?style=flat-square)](https://goreportcard.com/report/github.com/AnalogJ/capsulecd)\n[![GitHub release](http://img.shields.io/github/release/AnalogJ/capsulecd.svg?style=flat-square)](https://github.com/AnalogJ/capsulecd/releases)\n[![Docker Pulls](https://img.shields.io/docker/pulls/analogj/capsulecd.svg?style=flat-square)](https://hub.docker.com/r/analogj/capsulecd)\n[![Github All Releases](https://img.shields.io/github/downloads/analogj/capsulecd/total.svg?style=flat-square)](https://github.com/AnalogJ/capsulecd/releases)\n\n\u003c!-- \n[![Gemnasium](https://img.shields.io/gemnasium/analogj/capsulecd.svg)]()\n--\u003e\n\n\n\nCapsuleCD is a generic Continuous Delivery pipeline for versioned artifacts and libraries written in any language. \nIts goal is to bring automation to the packaging and deployment stage of your library release cycle.\nCapsuleCD is incredibly flexible, and works best when implemented side-by-side with a CI pipeline.\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://analogj.github.io/capsulecd\"\u003e\n  \u003cimg width=\"800\" src=\"https://cdn.rawgit.com/AnalogJ/capsulecd/master/capsulecd-screencast.png\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nA short list of the features...\n\n* Supports libraries written in any language. Has built-in support for \n\t* Chef Cookbooks\n\t* Python Pip\n\t* NodeJS Npm Packages\n\t* Ruby Gems\n\t* Golang Packages\n* Highly configurable\n* Follows language/library best practices. Including things like:\n\t* automatically bumping the semvar version number\n\t* regenerating any `*.lock` files/ shrinkwrap files with new version\n\t* creating any recommended files (eg. `.gitignore`) \n\t* validates all dependencies exist (by vendoring locally)\n\t* vulnerability scanning in dependencies\n\t* running unit tests\n\t* linting library syntax\n\t* source formatting\n\t* generating code coverage reports\n\t* updating changelog\n\t* uploading versioned artifact to community hosting service (rubygems/supermarket/pypi/etc)\n\t* creating a new git tag \n\t* pushing changes back to source control (github)\n\t* creating a new release in source control (github) and attaching any common artifacts\n\t\n## Links\n\n* Source: \u003chttp://github.com/AnalogJ/capsulecd\u003e\n* Bugs:   \u003chttp://github.com/AnalogJ/capsulecd/issues\u003e\n\n# Introduction\n\n## What is CapsuleCD\n\nCapsuleCD is a generic Continuous Delivery pipeline for versioned artifacts and libraries written in any language. \nIts goal is to bring automation to the packaging and deployment stage of your library release cycle.\nIt automates away all the common steps required when creating a new version of your library.\n\n## Why use CapsuleCD\nAt first glance, it seems simple to publish a new library version. Just bump the version number and publish, right?\nWell, not always:\n\n- If your library includes a Gemfile.lock, Berksfile.lock or other common lock files, you'll need to regenerate them as the old version number is embedded inside. \n- Everyone runs their library unit tests before creating a new release (right?!), but what about validating that your [library dependencies exist](http://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/) (maybe in your Company's private repo)?\n- How about linting your source, to ensure that it follows common/team conventions? \n- Who owns the gem? Is there one developer who has the credentials to push to RubyGems.org? Are they still on your team/on vacation? \n- Did you remember to tag your source when the new version was created (making it easy to determine what's changed between versions?)\n- Did you update your changelog?\n\nCapsuleCD handles all of that (and more!) for you. It pretty much guarantees that your library will have proper and\nconsistent releases every time. CapsuleCD is well structured and fully tested, unlike the release scripts you've manually\ncobbled together for each library and language. It can be customized as needed without rewriting from scratch. The best\npart is that CapsuleCD uses CapsuleCD to automate its releases. We [dogfood](https://en.wikipedia.org/wiki/Eating_your_own_dog_food)\nit so we're the first ones to find any issues with a new release.\n\n## How do I start?\nYou can use CapsuleCD to automate creating a new release from a pull request __or__ from the latest code on your default branch.\n\n### Automated pull request processing:\n\nHere's how to use __docker__ to merge a pull request to your Ruby library\n\n\tdocker run \\\n    -e CAPSULE_SCM_GITHUB_ACCESS_TOKEN=123456789ABCDEF \\\n    -e CAPSULE_SCM_REPO_FULL_NAME=AnalogJ/gem_analogj_test \\\n    -e CAPSULE_SCM_PULL_REQUEST=4 \\\n    -e CAPSULE_RUBYGEMS_API_KEY=ASDF12345F \\\n    AnalogJ/capsulecd:ruby capsulecd start --scm github --package_type ruby\n\nOr you could download the latest linux [release](https://github.com/AnalogJ/capsulecd/releases), and call CapsuleCD\ndirectly to merge a pull request to your Python library:\n\n\tCAPSULE_SCM_GITHUB_ACCESS_TOKEN=123456789ABCDEF \\\n\tCAPSULE_SCM_REPO_FULL_NAME=AnalogJ/pip_analogj_test \\\n\tCAPSULE_SCM_PULL_REQUEST=2 \\\n\tCAPSULE_PYPI_USERNAME=AnalogJ \\\n\tCAPSULE_PYPI_PASSWORD=mysupersecurepassword \\\n\tcapsulecd start --scm github --package_type python\n\t\n### Creating a branch release\n\n\tTODO: add documentation on how to create a release from the master branch without a pull request. Specify the env variables required. \n\t\n# Engine\nEvery package type is mapped to an engine class which inherits from a `EngineScm` class, ie `EnginePython`, `EngineNode`,\n`EngineRuby` etc. Every SCM type is mapped to a SCM class, ie `ScmGithub`. When CapsuleCD starts, it initializes the\nspecified Engine, and loads the correct SCM module. Then it begins processing your source code step by step.\n\nStep | Description\n------------ | ------------ \npipeline_init_step | This will initialize the SCM client, ensuring that we can authenticate with the git server\nscm_retrieve_payload_step | If a Pull Request # is specified, the payload is retrieved from SCM api, otherwise the repo default branch HEAD info is retrived.\nscm_process_pull_request_payload __or__ scm_process_push_payload | Depending on the retrieve_payload step, the merged pull request is cloned, or the default branch is cloned locally\nassemble_step | Code is built, which includes adding any missing files/default structure, version bumping, etc.\ndependencies_step | Download package dependencies\ncompile_step | Optional compilation of source into binaries\ntest_step | Run the package test runner(s) (eg. npm test, rake test, kitchen test, tox), linter, formatter \u0026 dependency vulnerbility scanner\npackage_step | Clean any unnecessary files, commit any local changes and create a git tag. Nothing should be pushed to remote repository\ndist_step | Push the release to the package repository (ie. npm, chef supermarket, rubygems)\nscm_publish | Push the merged, tested and version updated code up to the source code repository. Also do any source specific releases (github release, asset uploading, etc)\n\n# Configuration\nSpecifying your `GITHUB_ACCESS_TOKEN` and `PYPI_PASSWORD` via an environmental variable might make sense, but do you \nreally want to specify the `PYPI_USERNAME`, `REPO_FULL_NAME` each time? Probably not. \n\nCapsuleCD has you covered. We support a global YAML configuration file (that can be specified using the `--config_file`\nflag), and a repo specific YAML configuration file stored as `capsule.yml` inside the repo itself.\n\n## Setting Inheritance/Overrides\nCapsuleCD settings are determined by loading configuration in the following order (where the last value specified is used)\n\n- system YAML config file (`--config-file`)\n- repo YAML config file (`capsule.yml`)\n- environmental variables (setting in capital letters and prefixed with `CAPSULE_`)\n\n## Configuration Settings\n\nCheck the [`example.capsule.yml`](example.capsule.yml) file for a full list of all the available coniguration options.\n\nAs mentioned above, all settings can be specified via Environmental variable. All you need to do is convert the setting\nto uppercase and then prefix it with `CAPSULE_`. So `pypi_password` can be set with `CAPSULE_PYPI_PASSWORD` and\n`engine_cmd_test` with `CAPSULE_ENGINE_CMD_TEST`\n\n### Example System Configuration File\n\nHere's what an example system configuration file might look like:\n\n```\nscm_git_parent_path: /srv/myclonefolder\nscm_github_api_endpoint: https://git.mycorpsubnet.example.com/v2\nscm_github_web_endpoint: https://git.mycorpsubnet.example.com/v2\n```\n\n## Step pre/post hooks and overrides\n\nCapsuleCD is completely customizable, to the extent that you can run your own Ruby code as `pre` and `post`\nhooks before every step. To add a `pre`/`post` hook or override a step, just modify your config `yml` file by\nadding the step you want to modify, and specify `pre` or `post` as a subkey. Then specify your shell commands as a list\n\n\t---\n      scm_init:\n        pre:\n          - echo \"override pre_scm_configure\"\n          - `git clone ...`\n        post: |\n          # do additional cleanup or anything else you want.\n          - echo \"override post_scm_configure\"\n      assemble_step:\n        post: |\n          # this post hook runs after the assemble_step runs\n          - echo \"override post_build_step\"\n\n# Testing\n\n## Test suite and continuous integration\n\nCapsuleCD provides an extensive test-suite based on `go test` and a full integration suite which uses `go-vcr`.\nYou can run all the integration \u0026 unit tests with `go test $(glide novendor)`\n\nCircleCI is used for continuous integration testing: \u003chttps://circleci.com/gh/AnalogJ/capsulecd\u003e\n\n# Contributing\n\nIf you'd like to help improve CapsuleCD, follow the instructions in [CONTRIBUTING.md](CONTRIBUTING.md)\n\nNote that if you would like to do development without Docker, you'll also need to ensure that you have the `git2go` dependencies installed on your machine.\nYou can install these dependencies by using your system's package manager.\n\n\t- openssl\n\t- libgit2\n\t- libssh2\n\nWork your magic and then submit a pull request. We love pull requests!\n\nIf you find the documentation lacking, help us out and update this README.md.\nIf you don't have the time to work on CapsuleCD, but found something we should know about, please submit an issue.\n\n## To-do List\n\nWe're actively looking for pull requests in the following areas:\n\n- CapsuleCD Engines for other languages\n\t- C#\n\t- Objective C\n\t- Dash\n\t- Java\n\t- Lua\n\t- Rust\n\t- Scala\n\t- Swift\n\t- [Any others you can think of](https://libraries.io/)\n- CapsuleCD Sources\n\t- GitLab\n\t- Bitbucket\n\t- Beanstalk\n\t- Kiln\n\t- Any others you can think of\n\n\n# Versioning\n\nWe use SemVer for versioning. For the versions available, see the tags on this repository.\n\n# Authors\n\nJason Kulatunga - Initial Development -  [@AnalogJ](https://github.com/AnalogJ)\n\n# License\n\nCapsuleCD is licensed under the MIT License - see the\n[LICENSE.md](https://github.com/AnalogJ/capsulecd/blob/master/LICENSE.md) file for details\n\n\n\n\n\n\n# References\n- https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1\n- http://matthewbrown.io/2016/01/23/factory-pattern-in-golang/\n- https://medium.com/@matryer/5-simple-tips-and-tricks-for-writing-unit-tests-in-golang-619653f90742\n- http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/\n- https://stackoverflow.com/questions/6395076/using-reflect-how-do-you-set-the-value-of-a-struct-field\n- https://medium.com/@skdomino/writing-better-clis-one-snake-at-a-time-d22e50e60056\n- https://stackoverflow.com/questions/15148331/test-naming-conventions-in-golang\n- https://medium.com/@povilasve/go-advanced-tips-tricks-a872503ac859\n- https://blog.golang.org/error-handling-and-go\n- http://blog.hashbangbash.com/2014/04/linking-golang-statically/\n- https://gist.github.com/danielfbm/ba4ae91efa96bb4771351bdbd2c8b06f\n- https://gist.github.com/danielfbm/37b0ca88b745503557b2b3f16865d8c3\n- https://stackoverflow.com/questions/37026399/git2go-after-createcommit-all-files-appear-like-being-added-for-deletion\n- https://stackoverflow.com/questions/25965584/separating-unit-tests-and-integration-tests-in-go\n- https://peter.bourgon.org/go-best-practices-2016/\n- http://golangcookbook.com/chapters/running/cross-compiling/\n- https://github.com/kelseyhightower/confd/blob/20b3d37da7aaa2c176c0612202c06c5ba4f7d987/docs/release-checklist.md\n- https://gist.github.com/Ehekatl/93b4ac1621771f2889cd99c7b7cfc2ec\n- https://github.com/sithembiso/git2go-build\n- https://gist.github.com/Ehekatl/93b4ac1621771f2889cd99c7b7cfc2ec\n- https://github.com/danielfbm/docker-go-libgit2/blob/master/Dockerfile\n- https://github.com/thockin/go-build-template\n- https://peter.bourgon.org/go-best-practices-2016/\n- https://golang.org/cmd/gofmt/\n- https://github.com/weaveworks/mesh/blob/master/lint\n- https://github.com/alecthomas/gometalinter\n- https://golang.org/cmd/vet/\n- https://medium.com/statuscode/the-9-most-popular-golang-links-from-2016-c49287d99448\n- https://medium.com/@sebdah/go-best-practices-testing-3448165a0e18\n- https://buildroot.org/\n- https://github.com/multiarch/crossbuild\n- https://github.com/Cimpress-MCP/go-git2consul/tree/crossbuild/build-multi\n- https://docs.codecov.io/docs/testing-with-docker\n- https://github.com/codecov/example-go\n- https://github.com/codecov/support/wiki/Codecov-Yaml#how-to-disable-a-single-ci-provider\n- https://github.com/gopheracademy/gopheracademy-web/blob/master/content/advent-2014/git2go-tutorial.md\n- https://stackoverflow.com/questions/2381665/list-tags-contained-by-a-branch\n- https://dmitri.shuralyov.com/blog/18\n- http://www.ryanday.net/2012/10/01/installing-go-and-gopath/\n- http://craigwickesser.com/2015/02/golang-cmd-with-custom-environment/\n- https://opencredo.com/why-i-dont-like-error-handling-in-go/\n- https://godoc.org/github.com/pkg/errors\n- https://blog.strapi.io/testing-npm-package-before-releasing-it-using-verdaccio-and-ngrok/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAnalogJ%2Fcapsulecd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAnalogJ%2Fcapsulecd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAnalogJ%2Fcapsulecd/lists"}