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

New server, deployment, CI/CD pipeline #907

Merged
merged 2 commits into from
Mar 19, 2023
Merged

Conversation

abandoned-prototype
Copy link
Collaborator

@abandoned-prototype abandoned-prototype commented Mar 11, 2023

Status

Ready for review

Description of Changes

Changes proposed in this pull request:

  • Setting up new servers that run OpenOversight as docker image instead of in a python environment.
    • This should allow us to more easily keep the python version updated and quickly move from 3.8 to 3.11
  • Changing the strategy of deploying the code to the server. The overall idea will stay the same: A push to develop will trigger a deployment to the staging server, pushing to main triggers a deployment to production.
  • The way this is executed has been updated.
    • Instead of circleCI I propose to use github actions to do the deployment. The reasons for that are that I think it has a larger number of people using it (which means there are more tutorials, more people creating actions, etc), that the results are better visible to everyone (I think), that no secrets have been stolen recently (https://circleci.com/blog/jan-4-2023-incident-report/) and we are already using it for tests.
    • Speaking of tests, tests will no longer run on push, only on pull requests. As long as every push to either develop or main is done via a PR this should be fine.
    • I also updated Fabric to its new version Fabric 2. We use fabric to relatively easily write scripts that connect from the github action server to our server via ssh and run the appropriate commands to create backups and deploy the code.
  • This PR also includes a necessary change to dart sass, backported from OrcaCollective (Thank you!!)
  • I was testing the github action in a separate branch to make sure everything works as intended. Here is the successful run that should be the same as pushing to develop or staging should look like: https://github.com/lucyparsons/OpenOversight/actions/runs/4394148748. The branch is here: https://github.com/lucyparsons/OpenOversight/tree/workflow-test

Notes for Deployment

Before merging, I actually need to change the name-server settings so that staging.openoversight.com points to the new server.

Tests and linting

  • I have rebased my changes on current develop

  • pre-commit checks pass

@@ -1,116 +1,17 @@
# unused - remove file once circleCI integration is removed
Copy link
Collaborator

Choose a reason for hiding this comment

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

I might be mistaken, but should this file now be removed assuming it encompasses a full shift away from CircleCI?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Originally I removed it, but then CircleCI shows up as a failed test with "no config file found" which I thought was distracting (and maybe even blocking the PR, not sure), so now I will remove the file once I removed that integration

@@ -24,7 +19,7 @@ jobs:
FLASK_APP: OpenOversight.app
strategy:
matrix:
python-version: [3.5, 3.6, 3.7, 3.8]
python-version: ["3.8", "3.9"]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Your PR vaguely mentioned eventually shifting to Python 3.11. Do we want to either add a bigger test matrix, or a comment saying we'll eventually expand the range here?

Also, on a similar note, I think it's worthwhile to specify the current Python version we're using in the Dockerhub description or tags or somewhere for issue traceability.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It might be worth it to see how far you can push this matrix. See if 3.10 and 3.11 work in the repository's current state, etc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, originally I thought I could make it go to 3.11, but both 3.10 and 3.11 failed some tests (https://github.com/lucyparsons/OpenOversight/actions/runs/4391087165). Probably just a library that needs an update version or something, but I decided I shouldn't try to fix that in this PR.

Good point about specifying the currently used version! I will see where I can add that.

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 also added your second point now @onemec. The python version is set in the workflow file and will also be present in the tag used for the package as can be seen in the example here from my workflow-test branch: https://github.com/lucyparsons/OpenOversight/pkgs/container/openoversight/versions (dev-py3.9). Thanks for the suggestion!

@onemec
Copy link
Collaborator

onemec commented Mar 12, 2023

Looks good to me overall, though I'll try to review in greater detail later this week.

@@ -1,3 +1,5 @@
@use "sass:math";
Copy link
Collaborator

Choose a reason for hiding this comment

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

This plugin is so fresh!

Copy link
Collaborator

@michplunkett michplunkett left a comment

Choose a reason for hiding this comment

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

Generally great with a few nits here and there.

@@ -0,0 +1,3 @@
yarn build
Copy link
Collaborator

@michplunkett michplunkett Mar 12, 2023

Choose a reason for hiding this comment

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

I'm not sure if it's absolutely necessary, but since you have it in the prod version, you should add #!/bin/bash to the top of this file.

It'd also be good to add comments on what it's doing like you did in the prod version.

Copy link
Collaborator

Choose a reason for hiding this comment

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

+1 to this!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good points, thanks! I added #!/bin/bash and made executable. Also added comments.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Noice!

OpenOversight/scripts/entrypoint_prod.sh Show resolved Hide resolved
@@ -1,14 +1,12 @@
{
"devDependencies": {
"jquery": "1.9.1 - 3",
Copy link
Collaborator

Choose a reason for hiding this comment

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

I appreciate that you were able to get rid of a good amount of plugins here, especially jquery. It's crazy how long that plugin has stuck around.

@@ -0,0 +1,43 @@
FROM python:3.8-slim-bullseye as base
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think some general comments here would be helpful.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Agreed! I mostly copied this, but now looking at it again, I think I should be able to remove some of these packages. So I will do that first and then add comments why we need each of the remaining pieces.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added some comments now and removed the script that installs sqlite which is unused.

@@ -0,0 +1,154 @@
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

Though many of these functions are quite intuitive, I think it'd be worthwhile to at least have some function level comments on them. You don't need to put parameter level comments, though I do prefer them, but I think we should have at least Class, function, etc. comments in place.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good suggestion. I added some doc-strings and task help which would show up when using invoke --help deploy for example

Copy link
Collaborator

@AetherUnbound AetherUnbound left a comment

Choose a reason for hiding this comment

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

This looks great! I have a few comments, nothing blocking though 😄

@@ -0,0 +1,3 @@
yarn build
Copy link
Collaborator

Choose a reason for hiding this comment

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

+1 to this!


services:
web:
image: ghcr.io/lucyparsons/openoversight:${DB_IMAGE_TAG}
Copy link
Collaborator

Choose a reason for hiding this comment

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

This doesn't seem to correspond to a database, should this be DOCKER_IMAGE_TAG instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good find, totally blanked here. Definitely should have DOCKER in the name, thanks!

tasks.py Outdated


def deploy_(c: Connection, config: HostConfig):
print("Start new deployment.")
Copy link
Collaborator

Choose a reason for hiding this comment

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

I know it's a little bit more work, but I'd recommend converting these from print to log.info statements and setting up a basicConfig to log at INFO level by default. This would help provide timestamps for when each statement is issued (I've found myself shaking my fist at myself in the past for not having timestamps when using print 😅).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thank you, I agree that it is very important to have. Unfortunately python makes logging so weird by default (time is parsed with a comma instead of decimal for microseconds and in local time), so there are some extra lines to make it acceptable.

tasks.py Outdated
Comment on lines 85 to 121
pwd = io.StringIO(config.github_token)
print("Get new production docker image.")
c.run(
f"docker login ghcr.io -u {config.github_user} --password-stdin",
in_stream=pwd,
echo=True,
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Very cool!


env:
image_name: lucyparsons/openoversight
# env_mapping: {"develop": "staging", "main": "prod"}
Copy link
Collaborator

Choose a reason for hiding this comment

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

If these bits are gonna be commented out, I'd be game for just deleting them from the 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 had preferred to keep this in the code (not put it in a variable) but I somehow couldn't make that work. I left this here so it's easier to for people to make sense of it, even if they cannot see the variable settings (which might require admin rights to see, not sure)

tasks.py Outdated
Comment on lines 20 to 21


Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: I think it'd be worth getting rid of these two empty new lines.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

Copy link
Collaborator

Choose a reason for hiding this comment

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

This (and various other nitpicky things) can be auto-fixed with pre-commit hooks (like end-of-file-fixer here) in case we care to standardize this, though definitely not urgent.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we have a formatter in place right now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, we do have pre-commit hooks in place, including the end-of-file-fixer (see https://github.com/lucyparsons/OpenOversight/blob/develop/.pre-commit-config.yaml) and they ran over this PR: https://github.com/lucyparsons/OpenOversight/actions/runs/4458996732/jobs/7831175755
These extra empty lines were in the middle of a file, not at the end


@dataclass
class HostConfig:
"""HostConfig collects various parameters for each deployment (prod, staging, etc)"""
Copy link
Collaborator

@michplunkett michplunkett Mar 15, 2023

Choose a reason for hiding this comment

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

Nit: Top line documentation comments should look like:

"""
HostConfig collects various parameters for each deployment (prod, staging, etc).
"""

It's easier to read and is more standard from my understanding.

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 pydocstyle checker (part of our pre-commit check) appears to disagree. It's code D200 in this list https://www.pydocstyle.org/en/stable/error_codes.html

Copy link
Collaborator

Choose a reason for hiding this comment

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

Works for me in that case. It looks like it's good to go!

tasks.py Outdated
Comment on lines 73 to 74
"""Return a HostConfig based on given environment and github user and token.
Github user and token can be omitted if no connection to github is needed.
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit:

"""
Return a HostConfig based on given environment and github user and token.
Github user and token can be omitted if no connection to github is needed.
"""

Copy link
Collaborator

Choose a reason for hiding this comment

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

The same goes for the rest of the docstrings.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Changed this one (because it is multi-line)



@task(
help={"environment": "'staging' or 'prod' indicating which environment to target"}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: It looks like we use this string at least 3 times, so it'd be worth saving the key and value to a constant, imo.

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 was thinking about that. There is the downside of the help strings potentially not being updated if something changes, but the plus is that it is also a comment to anyone reading the code, so I am leaning to keep it as it is

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm here for that.

Copy link
Collaborator

@michplunkett michplunkett left a comment

Choose a reason for hiding this comment

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

Some small nits here and there, but otherwise fantastic work!

* Add workflow to build image and push to ghcr.io
* Append to workflow to also deploy image to staging/prod
* Remove files for old deployment
@abandoned-prototype
Copy link
Collaborator Author

abandoned-prototype commented Mar 19, 2023

I did a force push to squash the commits from the code review into the original commit to be able to do a merge commit now and maintain the original cherry-picked commit from the OrcaCollective's fork without adding multiple tiny commits to the projects history. The "Compare" button (https://github.com/lucyparsons/OpenOversight/compare/2a812ec9acf6c71d21831cd466e04fbda646d7a3..ea618af46af03408159f125153a4a883ffe8d356) verifies the before and after are identical.

@abandoned-prototype abandoned-prototype merged commit cbf336f into develop Mar 19, 2023
@abandoned-prototype abandoned-prototype deleted the new-deployment branch March 19, 2023 05:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants