Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move build pipeline to circleci #4923

Merged
merged 5 commits into from Dec 7, 2021
Merged

move build pipeline to circleci #4923

merged 5 commits into from Dec 7, 2021

Conversation

LeoMcA
Copy link
Collaborator

@LeoMcA LeoMcA commented Oct 14, 2021

mozilla/sumo#910

Opened as a draft, because it's not backwards-compatible with Jenkins (as I'd hoped) because of the changes to Dockerfile and docker-compose.yml, so we can't merge until we're ready to remove Jenkins (and that requires figuring out the staticfiles -> s3 piece, or an alternative).

Comments welcome, a few steps in the Dockerfile might be a bit unusual or convoluted to allow more efficient caching - please point out if you're confused by anything so I know where to add comments.

.circleci/config.yml Outdated Show resolved Hide resolved
Copy link
Collaborator

@akatsoulas akatsoulas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My first thought is to extract from this PR anything that can be merged into the existing implementation and affects Circle CI. After that just re-open this PR (minus the merges) in a new project in order to get some flexibility instead of pilling commits on top of a draft PR. Thoughts?

.circleci/config.yml Show resolved Hide resolved
@mozilla mozilla deleted a comment from Am0504050720 Oct 18, 2021
Dockerfile Show resolved Hide resolved
Dockerfile Show resolved Hide resolved
Dockerfile Outdated Show resolved Hide resolved
@LeoMcA LeoMcA force-pushed the new-build-pipeline branch 3 times, most recently from 79a673f to f8dafe9 Compare November 15, 2021 17:35
@LeoMcA LeoMcA force-pushed the new-build-pipeline branch 3 times, most recently from 4336f6d to 22fb209 Compare November 24, 2021 18:08
@LeoMcA
Copy link
Collaborator Author

LeoMcA commented Nov 29, 2021

This should now be feature complete, after implementing s3 push and proper l10n management.

For the latter, I adjusted the approach we used in Jenkins which was:

  1. pull mozilla-l10n/sumo-l10n repo
  2. lint
  3. if lint fails, abort
  4. push to mozilla-it/sumo-l10n-prod repo
  5. pull from mozilla-it/sumo-l10n-prod repo
  6. compile

This approach lacked nuance, and had the effect of losing rather a lot of localisations if just one file failed linting.

The new approach in l10n-fetch-lint-compile.sh is something like:

  1. pull mozilla-l10n/sumo-l10n repo
  2. lint each file individually
  3. if lint fails for a file, find what commit the file was last changed in, and checkout the file from that commit
  4. lint file again, if it fails goto step 3
  5. compile

This way if one locale has a failing file, the rest still keep their most up to date localisations.

Currently all our files pass linting (though msgfmt shows an error for some, which we should fix in the sumo-l10n repo, and then apply that same git backtracking logic to if msgfmt shows any errors as well), but you can test this locally by checking out a known bad commit in the sumo-l10n repo, then running the script:

cd locale
git checkout 3f359bd6868e3355f46fa81ea00f7edb9455e183
cd ../
./scripts/l10n-fetch-lint-compile.sh

You'll see a bunch of lint returned an error, trying 247e1c5812ef1a749130da96a3e41192912bff48 style messages, and running git status on the locale repo will show that the most recent "good" versions of the failing files have been checked out.

You can see a pretend main branch commit here: https://app.circleci.com/pipelines/github/mozilla/kitsune/1561/workflows/85bc7807-9bbd-4864-8f26-159d9e9e60bc/jobs/4283 (with a slightly adjusted config, to avoid uploading static files to the prod s3 bucket).

I think next steps are deploying a docker image from https://hub.docker.com/r/mozilla/kitsune/tags to stage to test the image is good.

@akatsoulas akatsoulas marked this pull request as ready for review November 30, 2021 10:40
Copy link
Collaborator

@akatsoulas akatsoulas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to go through the locales but what's in this review won't be affected by that

command: ./bin/dc.sh run test ./bin/run-mocha-tests.sh
- when:
condition:
equal: [ main, << pipeline.git.branch >> ]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's build the prod image on main branch and on any branch that starts with something like prod-

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Building on this, how about splitting the jobs a bit more (lint, test-js, unittests, build). Then we can use the workflows to run them in parallel and have a conditional in the workflow to build only under circumstances (eg on main and prod-*)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about splitting the jobs a bit more (lint, test-js, unittests, build).

This was my initial approach, however I couldn't immediately figure out how to share the docker context between each job, and so each had to build the image again completely from scratch - which took rather a long time. So I opted for the simpler (faster) approach first, to avoid this PR getting too unwieldily.

But my thought was, once merged, we can explore a bit more of the features Circle has to offer - like "proper" workflows, pretty test result output, and parallel tests.

.circleci/config.yml Outdated Show resolved Hide resolved
name: Build prod image
command: DOCKER_BUILDKIT=1 ./bin/dc.sh build --progress=plain prod
- run:
name: Push prod image
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could move Push prod image and Upload staticfiles outside of the job and treat them as reusable components

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not quite sure what you mean here

.circleci/config.yml Outdated Show resolved Hide resolved
docker-compose.ci.yml Outdated Show resolved Hide resolved
docker-compose.ci.yml Outdated Show resolved Hide resolved
- elasticsearch7
- redis

prod:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To allow us to do docker-compose build prod and end up with an appropriately tagged image

@@ -1,5 +0,0 @@
#!/bin/bash

source /venv/bin/activate
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this needed any more? Is this replaced by something else?

Copy link
Collaborator Author

@LeoMcA LeoMcA Dec 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we were/are using it anywhere!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used by mariadb in the docker-file

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure that's coming from inside the mariadb image (especially since it's called docker-entrypoint.sh not just entrypoint.sh)

docker/bin/upload-staticfiles.sh Outdated Show resolved Hide resolved
kitsune/sumo/jinja2/base.html Show resolved Hide resolved
@akatsoulas
Copy link
Collaborator

@smarnach could you have a look at this PR? It's mostly done but it would be nice if we could get a second pair of eyes before merging.

Copy link
Contributor

@smarnach smarnach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes here look good from an ops perspective.

It's not quite clear to me how the condition for pushing to Docker Hub works. If I look at the build for the last commit in this PR, it looks like it pushed a new tag to Docker Hub. If I look at the condition, I think it shouldn't have. What's the idea here?

@@ -10,22 +12,59 @@ jobs:
command: |
sudo pip install --upgrade pre-commit==2.15.0
pre-commit run --all-files
test-and-build:
docker:
- image: circleci/python:3.9-buster
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use the 3.9-bullseye tag, which seems closer to what's used inside the Docker image? Probably doesn't make much of a difference.

@akatsoulas
Copy link
Collaborator

The changes here look good from an ops perspective.

It's not quite clear to me how the condition for pushing to Docker Hub works. If I look at the build for the last commit in this PR, it looks like it pushed a new tag to Docker Hub. If I look at the condition, I think it shouldn't have. What's the idea here?

The idea here is to push to docker-hub always from the main branch but also have the ability to push an image in different branches. In Jenkins there is an image pushed to every branch. In circle-ci we agreed that everything that starts with prod- should trigger an image push.

@smarnach
Copy link
Contributor

smarnach commented Dec 6, 2021

The idea here is to push to docker-hub always from the main branch but also have the ability to push an image in different branches. In Jenkins there is an image pushed to every branch. In circle-ci we agreed that everything that starts with prod- should trigger an image push.

That's how I read the condition as well. I still wonder why the last build for this PR pushed an image, since this branch is called new-build-pipeline. Shouldn't this only push an image once merged?

@akatsoulas
Copy link
Collaborator

I believe that condition was added as part of the review process which also was the latest commit that was built from both the new-build-pipeline and the prod-new-build-pipeline branches. The image hash though in the docker repo seems to be coming from the prod-new-build-pipeline branch. That said, I believe it's worth double checking this by triggering one more build in the current branch and make sure that it won't push to docker hub.

Copy link
Collaborator

@akatsoulas akatsoulas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few comments that require changes but overall this is looking good. Nice work!
I am more than happy to have another pass if you would like for the new changes. r+wc

@@ -1,5 +0,0 @@
#!/bin/bash

source /venv/bin/activate
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used by mariadb in the docker-file

docker/bin/upload-staticfiles.sh Outdated Show resolved Hide resolved
.circleci/config.yml Outdated Show resolved Hide resolved
Dockerfile Show resolved Hide resolved
.circleci/config.yml Show resolved Hide resolved
.circleci/config.yml Outdated Show resolved Hide resolved
echo "po status for commit ${head_hash}:" > $postatus_file
echo -e "(if nothing appears below, no errors were detected)\\n" >> $postatus_file

function lintpo() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if subsequent commits have errors?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script will keep backtracking until it finds a file which passes linting - the beauty of doing this on a git repo is that since all the files right now pass linting, we know that there'll always be a file we can (eventually) get back to which passes. That may take rather a while in the worst case, but if we notice there's a locale which is failing for a few builds in a row we can always submit a PR to fix the error.

@LeoMcA
Copy link
Collaborator Author

LeoMcA commented Dec 7, 2021

The image hash though in the docker repo seems to be coming from the prod-new-build-pipeline branch. That said, I believe it's worth double checking this by triggering one more build in the current branch and make sure that it won't push to docker hub.

Yes I think this is a quirk of the circleci/github integration - since I've pushed the same commits to both the new-build-pipeline and prod-new-build-pipeline branches, it's linking to the latter from this commit (I guess because I pushed there first?)

The latest commit is only on this branch, so we should see this stopping after tests: https://circleci.com/gh/mozilla/kitsune/4296

I've deployed https://hub.docker.com/layers/mozilla/kitsune/prod-8b6e26/images/sha256-eec231404190c0018f85e3e85739c2ed76889c52489d4d00ba388c5a01346985?context=explore to stage and everything seems to be working fine!

@LeoMcA LeoMcA merged commit 2871ee4 into main Dec 7, 2021
2 checks passed
@LeoMcA LeoMcA deleted the new-build-pipeline branch December 7, 2021 11:57
@smarnach
Copy link
Contributor

smarnach commented Dec 7, 2021

Yes I think this is a quirk of the circleci/github integration - since I've pushed the same commits to both the new-build-pipeline and prod-new-build-pipeline branches, it's linking to the latter from this commit (I guess because I pushed there first?)

Thanks for the explanation. I think Circle CI only runs once for each commit, and the builds are linked by commit hash, so if you pushed on the prod-… branch first that would explain the behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants