Pregunta

In the project I'm working for we're having a continuous deployment setup. The goal is to always install the latest working build to production, unless someone manually overrides this functionality.

In order to make this working we

  1. Run static code analysis
  2. Run unit tests
  3. Run integration tests
  4. Run automatic UI tests, to the extent this is feasible

If any of the above steps fail, the build process is halted, and the build marked as failed. If the installation package is created it is then in steps installed to

CI --> staging --> production

At each step we run a integration and UI tests for the environment, to make sure we didn't introduce some new things which fail on on the subsequent environments. If none of the tests fail, and N minutes pass without anyone pressing the panic button, the build gets promoted to the next env. If the tests fail, we want to delete the package, and discard it completely. The installation packages are, however, delivered to other servers, so we need to run a bunch of remote (shell) scripts to make this step happen.

The problem is, that there are a big set of failure cases which we cannot reliably test in the normal automated cycle, e.g. page layout, or some integrations fail only production and so on.

So the actual question: How shall I demote/delete builds, once they've been promoted? Is it possible to either run a remote script when doing delete build or use any of the promotion plugins to achieve this functionality? Is there some think-outside-the-box solution for this that I might not have thought about?

¿Fue útil?

Solución 2

This might be a very particular case, but we decided against creating a separate job for removing the builds, for the very simple reason of keeping all the logging related to a specific build number in one single place. The setup was the following:

Promotion here means make the installation package (RPM) available to the given server, where auto-update handles the actual upgrade of the package.

We have one main build, that builds every time a new commit is available. We had some fine-tuning related to quiet times etc. but basically every new pushed set of commits resulted in a new build. The build contains all the relevant and available testing, which is far from being complete, and probably never will be.

Every hour a separate promotion step handles promotion from staging to production. This build kicks off a separate promotion which takes the latest accepted build from CI to staging. There is a 30min delay before builds were promoted CI-->staging, to prevent accidental promotions for last second commits. Delays were achieved with some bash find scripting. The order of promotions is this, to make sure a build is available in staging for (at least) one hour before going to promotion.

The actual answer: The promotion steps were done as separate builds. In order to do a real promotion, rather than a separate build with a separate log, the build kicks off an actual promotion in the main build, using curl and calling the remote HTTP API. This leaves a relevan promotions star in the main build log. Using different colors, the promotions are visible with one look.

To demote builds I decided to create a separate "demote build" promotion step. This would then issue a purple star as a sign of the build being defective, and thus removed. The demotion is done by accessing the correct build in the UI, and pressing the "Remove build" button. No automation has been added to this step, but by creating a separate test step, it would be fairly easy to automate the demotion as well. We, however, have not gotten quite this far yet.

The benefits of this approach include

  • A build is deleted by accessing the failed build, not by providing parameters. Makes it much easier to document, and get right under pressure
  • Having a "panic button" like this available for anyone to press, builds trust and ownership for the process not only amongst the developers but also managers and DevOps.
  • It's dead simple to spot dead builds, as the log is available besides the other promotion logs
  • Having all the relevant promotion calls in the same build makes further scripting easier

Acute things we still have to improve include automating the testing on the later stages of the build pipeline, and also a suitable way of downgrading builds after demotion. E.g. in production a defective build and a demotion must always lead to installing the last good build, which has turned out to be fairly hard to achieve. Production data centers are rarely allowed to be accessible to this level from the development DC where the CI system sits. Also stopping and starting the build pipeline must be automated, as else there is the chance of slipping back to the manual state.

Naturally, in the spirit of continuous improvement, there are always things to improve. The whole setup is something of a bash/perl scripting mess, but since it's scripted and repeatable, there is always the option of improving one small piece at a time. The most important thing is the automation, as it allows for incremental steps, which any manual steps more or less prevent.

Otros consejos

Instead of deleting builds manually, you may write a Jenkins job that accepts the build number as a parameter, deletes it, and then does the rest of the housekeeping. You can configure Jenkins access privileges so that people do not delete builds manually by accident.

For anyone looking for an easy way to delete a build with custom steps:

  • Create a 'defective' promotion.
  • Make it manually triggered.
  • Force it run on the master.
  • Add a choice parameter DELETE with choices NO and YES.
  • Add action Execute Shell.

_

if [ "${DELETE}" == "YES" ]; then
  # TODO: my custom steps
  curl -X POST ${PROMOTED_URL}/doDelete"
fi

To delete a build now, just go to promotions, flip the choice to YES and click approve.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top