Skip to content
This repository has been archived by the owner on Aug 7, 2023. It is now read-only.

Look into deployment from CI #18

Open
Arcanemagus opened this issue Sep 1, 2017 · 22 comments
Open

Look into deployment from CI #18

Arcanemagus opened this issue Sep 1, 2017 · 22 comments

Comments

@Arcanemagus
Copy link
Member

Arcanemagus commented Sep 1, 2017

Automated Deployment

We have a mostly complete setup for getting automated deployment of your package whenever commits are made that should be released out to the users. If you are just interested in how to get this working, see the Setup section. If you are curious about all of the tools that make this possible and how they interact see the Description section. See the Limitations section for current potential blockers for enabling this in your repository, feel free to comment below with any additional questions or clarifications.

Setup

Currently you must have Travis CI configured on the project in order to utilize this setup, this is a limitation of the tool used to verify that the commit messages are following the proper format and is being looked into.

Required Environment Variables

You must have Admin level permissions on a repository in order to complete setup! If you need help with this please contact @Arcanemagus on the Atom Slack team.

The following environment variables are required to be configured in the environment by @semantic-release/apm-config:

  • ATOM_ACCESS_TOKEN: The value to use for this can be found here: https://atom.io/account
  • GITHUB_TOKEN: Follow these instructions to create a new token. When creating it you need to give it public_repo permissions:
    image

When you have values ready for these tokens you will need to add them to the environment for your repositories builds. The easiest way to do this is to do so from the web UI settings, for example: https://travis-ci.org/AtomLinter/linter-js-yaml/settings

When there simply add the values in the Environment Variables section, don't worry about the values as they are encrypted and in addition are not visible once added:

image

Alternatively you can follow these instructions to add the encrypted values directly into the repositories .travis.yml, like this.

Travis CI Build

The next step that likely needs additional work on your part is to configure the Travis CI build, the initial PR does some of the steps needed, however there are additional changes required to get a working setup.

You'll need to add a jobs and stages section in order to properly control the flow of the deployment. It's also likely that you will need to modify the stage that the build-package.sh script is running at, as the simplest setup is to have it as the install stage.

As most projects are running on Linux CI builds a good example setup can be found in the linter-js-yaml .travis.yml file. If you run into any issues getting things working feel free to contact me as above!

Profit?

Ideally the rest of the configuration should have been taken care of by the initial PR, so at this point any time commits are made that should trigger a release it will be taken care of automatically for you.

Description

If you are interested in all of the parts going into this, this is the section for you!

Commit Messages

At the heart of how all this works is the requirement that your commit messages all follow a specified standard, which lets the tools determine whether or not a release should be made, and if so what changes it will include that should be displayed to users.

Under the default configuration your commit messages will now be required to follow the Conventional Commits standard. This standard is quite flexible, with the default syntax being:

<type>[optional scope]: <description>

[optional body]

[optional footer]

The only important <types> are fix and feat, corresponding to a patch level change and minor level change respectively. If your commit message includes the words BREAKING CHANGE: at the start of the body or footer will trigger a major release of your package. Further details can be found on their website. Any <type> other than the ones listed above is ignored as far as releases are concerned, so feel free to use whatever you like, you can find some suggested types in the Angular Commit style, as that is what Conventional Commits are based on.

Additional commit message formats are supported, you can find a full list in the commit-analyzer options.

Commit Enforcement

The next important part is making sure that all commit messages actually fit within the chosen style, otherwise there wouldn't be a point to having a style 😆. This is accomplished with the commitlint tool, which allows you to lint your commit messages themselves, ensuring they fit within the style you have chosen. This tool is a standalone tool, and as nobody would remember to run it for every commit themselves, the Husky tool is used to automatically install git hooks when you run npm install, with these hooks being configured to run commitlint on your commit message before it is actually written to the repository. This tool is also configured to run within CI builds, preventing somebody from skipping the hook installation and trying to make a commit message that doesn't follow the required style.

Deployment

The last part is that during your CI builds on commits directly to the master branch the semantic-release utility is called that pulls all the commits done since the last release together, determines if any release should be done based on those commits, and what level it should be. It then generates a CHANGELOG entry, commits the changes necessary for the release, pushes it back up to GitHub, tags a release, and publishes it on apm. Magic! ✨

I'll let them describe the process in more detail over in their README.

Limitations

There are three major limitations to this process.

Commits must follow the standard

Without the commits following the standard the tool has no idea what they are doing and will likely just skip them. The configuration recommended requires all commits to follow the standard, letting it dictate what is included or not. An alternative way of working with this would be to drop this requirement and only do a "release commit" that follows the standard when you want to. That somewhat defeats the purpose of an automated system like this though, essentially delegating it to just running apm publish for you.

Only Travis CI is supported

This is primarily a limitation of the commitlint tool, I'm working on a version of the CI runner for this to work in the Circle CI environment, but haven't gotten many of the possible edge cases working yet.

Administrator access required to set it up

Many of the security benefits possible with automated deployments are currently actually required to be bypassed only for administrator accounts under this setup. This is because right now the process needed to do the deployment is done from within the CI builds, so they can't wait for all required CI builds to complete before running. I'll be following semantic-release/semantic-release#585 which is how they plan to work around this by creating their own GitHub app which could run as a separate "CI" process after all the required builds have finished.

Problems?

Again, if you run into any problems getting this running, feel free to contact @Arcanemagus on the Atom Slack team and I will work with you to get things running properly.


Note: The original description follows.

It would be great if we could deploy new versions from CI, allowing people with only write access to repositories with protected branches to still be able to deploy new versions.

There was some initial work towards this over in linter-clang by @keplersj here. It utilized an experimental deployment engine from travis-ci/dpl#401 discussed further in travis-ci/dpl#378.

@Arcanemagus
Copy link
Member Author

Arcanemagus commented Dec 22, 2017

It might be possible to write a plugin for semantic-release that supports APM.

@keplersj
Copy link

I was actually planning on writing one 😂

@keplersj
Copy link

Errmm... Maybe I'll wait? niklashigi/semantic-release-apm#4

@keplersj
Copy link

keplersj commented Dec 22, 2017

semantic-release/semantic-release#553 was just merged in - an APM config with semantic-release should be coming down soon.

In preparation might I suggest experimenting with commitlint configured with husky.

@Arcanemagus
Copy link
Member Author

And here's the first CD release of any AtomLinter package: https://github.com/AtomLinter/atom-linter-pug/releases/tag/v2.0.0

Most of the details of the implementation are in AtomLinter/atom-linter-pug#20, specifically AtomLinter/atom-linter-pug@9122172 to add a linter for commit messages to ensure they are in the format expected to properly allow automated changelog generation, and then AtomLinter/atom-linter-pug@89cea7f to actually configure the automated release tool. Note that stable channel builds must be the one chosen for semantic-release, that was fixed in AtomLinter/atom-linter-pug#22 with semantic-release/apm-config#7 filed to decide on the eventual solution.

@Arcanemagus
Copy link
Member Author

Some things to think on:

If the Angular commit message format isn't desired we start running into some big issues, primarily being that it isn't currently possible to change the commit message format used by GreenKeeper. So although you could change to another one of the allowed presets for regular commits, none of them will work for GK causing it to always fail the build.

At this point as far as I can see that means:

  • Completely custom plugins for semantic-release allowing things like label based determination of releases
  • PR to Greenkeeper allowing customization of the commit message.

@keplersj
Copy link

I prefer Renovate to GreenKeeper.

@smhxx
Copy link

smhxx commented Jan 21, 2018

Hmm... I hadn't heard of Renovate before, but I might consider switching to it; it looks like it has quite a few features that Greenkeeper doesn't (multiple package.json support! 😄) It does look like Angular is the only commit format it currently recognizes, though. I'm not sure what the default is.

(I lied. It can be configured to use any commit message format.)

I recently started using semantic-release on atom-ts-transpiler, and I quite like it. The Angular commit format is pretty easy to get used to (imo,) although for a project with many contributors having a tool like commitlint or commitizen seems like a good idea. Angular/conventional-commit seems to be a fairly widespread standard, so I would think that most contributors would have at least seen it before, if not used it personally.

@pvdlg
Copy link

pvdlg commented Jan 21, 2018

For information the default semantic-release commit analyzer plugin allow you to configure custom release rules.

So if you decide to use another commit format, you can still add a custom rule to make a release for GreenKeeper commits. Something like that:

{
  "release": {
      "releaseRules": [{ "message": "/^fix\\(package\\):/", "release": "minor"}]
  }
}

That said, a cleaner solution would be for Greenkeeper to allow customizing the commit messages.

@Arcanemagus
Copy link
Member Author

That said, a cleaner solution would be for Greenkeeper to allow customizing the commit messages.

I commented on the Greenkeeper issue to hopefully restart the discussion on getting this fixed there: greenkeeperio/greenkeeper#153 (comment)

for a project with many contributors having a tool like commitlint or commitizen seems like a good idea.

Yea, if the releases are to be based on the commit message format, something that enforces it is an absolute must which is why husky + commitlint was a great combination. commitizen suffers from a discoverability issue, but might also be nice to add.

I've seen rumblings of a common commit message format definition between the different tools in some of the issues I've been reading, but it seems like it hasn't come to pass yet.

I think I'm definitely starting to lean towards the idea of basing things on a commit message format. Although the method used for changelog generation in many of the packages currently (labels on issues/PRs) is very flexible and allows for easy onboarding of past changes, the enforcement of a common commit style definitely has advantages for multiple people working on the same repository and being able to scan the commit history to know what went on. The ability to merge commits between branches and know what release level that will cause is a definite bonus as well, although not currently something that would be taken advantage of here.

@Arcanemagus
Copy link
Member Author

Sent in a PR to Greenkeeper that has been merged: greenkeeperio/greenkeeper#612

This allows customization of the commit messages in Greenkeeper, allowing it to fit within different commit message formats. This still isn't as flexible for changelog generation as the current tool, but should be "good enough" for most of the repos.

@Arcanemagus
Copy link
Member Author

The ability to customize the commit message on Greenkeeper is now live in their production environment. 🎉

This was referenced Apr 15, 2018
@keplersj
Copy link

I think I've gotten a PR for every provider except for linter-pug (already configured), linter-bootlint, and linter-flex (weird error).

@ericcornelissen
Copy link

Among the things needed to be reconciled, an APM Token and GitHub Token will need to be added to this repo's continous integration (most likely Travis CI) configuration for automated deployments to work.

What are the names of the variables for these tokens?

@keplersj
Copy link

keplersj commented Apr 15, 2018

ATOM_ACCESS_TOKEN and GITHUB_TOKEN

@florianb
Copy link

@Arcanemagus, @keplersj Is it necessary to flood all linters with PRs without any word of introduction?

@Arcanemagus
Copy link
Member Author

@florianb I've actually posted about this a couple of times in the #linter-plugin-dev channel on the Atom Slack asking for feedback 😉.

There are a few things that I felt needed to be resolved before moving to this, the primary blocker that I see being that under the default configuration this only will be able to be fully implemented on Travis CI due to commitlint only having a runner for that CI service.

I tried building a runner for Circle CI, but their existing one relies on Travis CI providing an environment variable that lists the commit hash range and just parses that. Circle CI doesn't provide this and I was having issues determining what the appropriate range was in every situation (Circle CI's amazing flexibility causing issues for once instead of solving them 😆).

Danger was suggested as a potential way to work around this limitation/difficulty, I haven't had a chance to look into it myself.

I was planning on doing something similar once all the pieces were ready, but it would have been individual PRs tailored to the provider since otherwise they may get blindly merged without any real investigation (as has already happened to 2 of these).

@keplersj
Copy link

@florianb If the complaint is that I created 82 pull requests on most of the linter-* packages in the AtomLinter organization in the span of about an hour I apologize for the noise that created.

However, if the complaint is that all of these pull requests represent a unannounced proposal that came out of nowhere I will not apologize. We have been discussing and proposing different forms of implementation of continuous deployment within AtomLinter packages for just over 2 years now. This is not an unannounced proposal.

As I wrote in the body of every Pull Request, the branch was not meant to be merged without reconciliation. Because there are about 90 linter-* providers in the AtomLinter organization I felt some automation would be helpful in getting the tedious grunt work of this proposal along. While every provider is unique and requires some reconciliation, this proposal has a lot of parts that would've been the same among the providers. I aimed to implement the common parts and work to implement the unique parts in reconciliation later.

@Arcanemagus
Copy link
Member Author

@florianb I've updated the main post here with a massive FAQ/HOWTO for implementing this. Hopefully that helps clarify things!

@florianb
Copy link

florianb commented Apr 21, 2018 via email

@Arcanemagus
Copy link
Member Author

Since I just had to look this up again, noting this here for future improvement: https://probot.github.io/apps/commitlint/

@Arcanemagus
Copy link
Member Author

image

Example of that commitlint bot, looks like it will work to remove the requirement on running TravisCI 😁.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants