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
Conversation
There was a problem hiding this 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?
79a673f
to
f8dafe9
Compare
4336f6d
to
22fb209
Compare
22fb209
to
24694be
Compare
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:
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
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 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. |
There was a problem hiding this 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
.circleci/config.yml
Outdated
command: ./bin/dc.sh run test ./bin/run-mocha-tests.sh | ||
- when: | ||
condition: | ||
equal: [ main, << pipeline.git.branch >> ] |
There was a problem hiding this comment.
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-
There was a problem hiding this comment.
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-*)
There was a problem hiding this comment.
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.
name: Build prod image | ||
command: DOCKER_BUILDKIT=1 ./bin/dc.sh build --progress=plain prod | ||
- run: | ||
name: Push prod image |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
docker-compose.ci.yml
Outdated
- elasticsearch7 | ||
- redis | ||
|
||
prod: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this needed?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
)
The |
@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. |
There was a problem hiding this 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?
.circleci/config.yml
Outdated
@@ -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 |
There was a problem hiding this comment.
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.
The idea here is to push to docker-hub always from the |
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 |
I believe that condition was added as part of the review process which also was the latest commit that was built from both the |
There was a problem hiding this 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 |
There was a problem hiding this comment.
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
echo "po status for commit ${head_hash}:" > $postatus_file | ||
echo -e "(if nothing appears below, no errors were detected)\\n" >> $postatus_file | ||
|
||
function lintpo() { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
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! |
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. |
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
anddocker-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.