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

Rewrite server deploy script #1793

Merged
merged 11 commits into from
Oct 30, 2018
Merged

Rewrite server deploy script #1793

merged 11 commits into from
Oct 30, 2018

Conversation

paulmelnikow
Copy link
Member

@paulmelnikow paulmelnikow commented Jul 22, 2018

I haven't run this yet but I will do that when I run the deploy later today. Would appreciate an "eyeballs" review first!

To run this requires renaming private/secret.json to private/secret-production.json in the working tree used for deployment.

Goals:

  • Ensure production secrets are not used in development
  • Avoid modifying the current working tree
  • Avoid branch switching: make sure the current ref gets deployed
    • If something other than master is deployed, leave HEAD alone; don't reset to master
  • Ensure the build runs before server deploy (Accessing the website on a specific server has link breakage #1941)

This makes use of Git working trees, which is a relatively new but stable feature in Git. I was initially reluctant to use git worktree, mostly because I don't like adding new tooling that isn't necessary. The other alternative I experimented with was copying or re-cloning to an entirely separate working copy. This was messier and more brittle than using git worktree.

cc @espadrine

This requires renaming `private/secret.json` to `private/secret-production.json` in the working tree used for deployment.
@paulmelnikow paulmelnikow added the operations Hosting, monitoring, and reliability for the production badge servers label Jul 22, 2018
@paulmelnikow paulmelnikow had a problem deploying to shields-staging-pr-1793 July 22, 2018 13:39 Failure
Makefile Outdated
cp private/secret-production.json ${SERVER_TMP}/private/secret.json
cp Verdana.ttf ${SERVER_TMP}
git -C ${SERVER_TMP} add private/secret.json Verdana.ttf
git -C ${SERVER_TMP} commit -m '[DEPLOY] MUST NOT BE ON GITHUB'
Copy link
Member

Choose a reason for hiding this comment

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

That is a significant change in behavior. It feels like it does more than just use secret-production.json instead of secret.json. Could you explain this change further please?

Copy link
Member Author

Choose a reason for hiding this comment

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

Without a working tree, the solution as far as I can see is to:

  1. Back up the existing private/secret.json, if it exists
  2. Copy private/secret-production.json to private/secret.json
  3. Check it in
  4. Restore the original private/secret.json afterward

That has more moving parts than I'd like, seems brittle, and also seems like it could result in accidental data loss.

By moving the branch manipulation into a separate working tree, private/secret.json can be copied for deployment without needing to preserve the original.

The other change is how the branching is handled, which I'll respond to below.

Makefile Outdated
git checkout master
rm -rf ${SERVER_TMP}
git worktree prune
git worktree add -B production ${SERVER_TMP}
Copy link
Member

Choose a reason for hiding this comment

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

The use of git worktree feels a bit like tempting the devil. The use of -B in particular risks losing information without realizing.

In general, I prefer having deployment procedures so dumb that it takes a lot for them to go wrong, and when they do, they are dumb enough that it is simple to fix them.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I agree that deployment procedures should be as easy to reason about as possible. If they fail, they should fail in very safe ways.

To that end, I'd like to avoid modifying the existing working tree during deployment. I'd also like to avoid branch switching to make sure the current ref gets deployed. In the current process, if two servers are deployed at once, I believe the second one will get master. I'd also like to deploy the exact same front-end build to each server. There's no need to build it again and it's one less thing to reason about.

When I was working on #1774 I was initially reluctant to use git worktree, mostly because I don't like adding new tooling that isn't necessary. The other alternative I experimented with was copying or re-cloning to an entirely separate working copy. This was messier and more brittle than using git worktree.

I'm not thrilled with using -B. I took it from the github pages deploy, which starts with a git checkout -B gh-pages.

Before my change, the deploy commits happen on a detached head. Nothing is deleted in the process, however it's deleted right afterward. Without a branch, it's difficult to inspect what was pushed to the server. I don't like deleting data. However, it is not surprising that a deploy process would clobber a branch named production. I'd rather reserve a branch for the production deploy work than do it all on a detached head that gets tossed right after it runs.

Would you be more comfortable using a name that was really explicit like server-deploy-working-branch?

Copy link
Member Author

Choose a reason for hiding this comment

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

#1941 is another issue with the current scripts. git worktree has been working more reliably for deploy-gh-pages than the current deploy is for the servers.

@paulmelnikow
Copy link
Member Author

The use of git worktree feels a bit like tempting the devil. The use of -B in particular risks losing information without realizing.

In general, I prefer having deployment procedures so dumb that it takes a lot for them to go wrong, and when they do, they are dumb enough that it is simple to fix them.

Yes, the deploy process should be safe, simple, and reliable. Using worktree makes it safer, by not doing the work inside a tree, and in a way throws away less because the deploy branch sticks around after the deploy is done. It also lets you push the same build to each machine rather than running a new build for each one.

Let's not rush this discussion; I'll circle back.

@paulmelnikow paulmelnikow temporarily deployed to shields-staging-pr-1793 July 22, 2018 21:28 Inactive
@shields-ci
Copy link

shields-ci commented Jul 22, 2018

Messages
📖

✨ Thanks for your contribution to Shields, @paulmelnikow!

Generated by 🚫 dangerJS

@paulmelnikow paulmelnikow temporarily deployed to shields-staging-pr-1793 July 22, 2018 21:34 Inactive
@paulmelnikow
Copy link
Member Author

I can confirm that the current scripts, when aborted in the middle, leave a deploy commit hanging on the working copy. When I reset to last commit from master, Verdana.ttf, the server config, and the build are removed from the working copy.

Any thoughts about my comments?

@paulmelnikow
Copy link
Member Author

I continue to encounter issues where I accidentally run things using production credentials while deploying. I feel it's necessary to move forward with this. I will update it in light of #2178 and then it would be great if someone would please give a cursory 👍to merge it.

@paulmelnikow paulmelnikow changed the title Ensure production secrets are not used in development Rewrite server deploy script Oct 27, 2018
chris48s
chris48s previously approved these changes Oct 27, 2018
Copy link
Member

@chris48s chris48s left a comment

Choose a reason for hiding this comment

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

Accepting that I can't test this and haven't run it, I've had a read through the code and I can't see anything that looks obviously wrong or buggy. If this is the process you are actually using to deploy the site, I think it makes sense for the repo to reflect reality in this respect.

As an additional risk mitigation, do you think we should set up any branch names used in deployment with a branch protection rule in https://github.com/badges/shields/settings/branches to prevent us accidentally pushing it to GH?

@chris48s
Copy link
Member

This shouldn't be a blocker for this PR, but for the front-end part of the build/deploy, have you ever looked at this package: https://github.com/tschaub/gh-pages ?

@paulmelnikow
Copy link
Member Author

As an additional risk mitigation, do you think we should set up any branch names used in deployment with a branch protection rule in https://github.com/badges/shields/settings/branches to prevent us accidentally pushing it to GH?

It's not a bad idea. I just added branch protection for server-deploy-working-branch – see #1793 (comment) – and I'll update this to use the same.

@paulmelnikow
Copy link
Member Author

paulmelnikow commented Oct 29, 2018

Okay, this is updated.

I'll re-test it on a real deploy before merging.

Added: Done!

@paulmelnikow paulmelnikow merged commit 94611fb into master Oct 30, 2018
@shields-deployment
Copy link

This pull request was merged to master branch. This change is now waiting for deployment, which will usually happen within a few days. Stay tuned by joining our #ops channel on Discord!

After deployment, changes are copied to gh-pages branch:

@paulmelnikow paulmelnikow deleted the deploy-server branch October 30, 2018 21:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
operations Hosting, monitoring, and reliability for the production badge servers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants