-
Notifications
You must be signed in to change notification settings - Fork 135
[AINFRA-1533] Adopt git-crypt in this repo #14979
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
base: trunk
Are you sure you want to change the base?
Conversation
dc6517c to
703d297
Compare
📲 You can test the changes from this Pull Request in WooCommerce-Wear Android by scanning the QR code below to install the corresponding build.
|
|
📲 You can test the changes from this Pull Request in WooCommerce Android by scanning the QR code below to install the corresponding build.
|
e8ca34f to
79cf715
Compare
- Replace calls to `configure_apply` with calls to `.buildkite/git-crypt/unlock.sh` - Commit the prebuilt binary to use on our EC2 images on CI(1), alongside the Dockerfile that was used to create it(2) (1) In the future we'll probably pre-provision our custom Android AMI with it instead of shipping it inside each repo (2) In theory we could use `docker run --rm -v …` to run `git-crypt` from within the Docker container, instead of extracting the binary from the Docker image and committing that binary. But for this to work, that requires to not only map the repo's dir as volume in the container, but also map the repo mirror dir used during `git clone --reference` / listed in `.git/objects/info/alternates`; so that can get tricky in CI that uses that git mirrors mechanism. Besides, the binary is pretty small (200KB) and being able to run it directly without Docker is not only simpler but avoids pulling the docker image in the CI agent before we can run it.
a79527b to
be5c217
Compare
- Now that we migrated to `git-crypt`, the `WooCommerce/google-services.json` file _always_ exists in the repo (albeit encrypted if the repo was not git-crypt-unlocked after being cloned), the logic to decide when to copy the `google-services.json-example` file had to be adjusted - Also updated the `README.md` accordingly—to suggest external contributors to copy the example file
be5c217 to
0509840
Compare
Since that command switched branches, we don't want it to fail or to encounter a case of modified files if the `.gitattributes` changed between the 2 branches and some git-crypt'ed files end up being marked as modified during the switch because of it.
I an hoping that we shouldn't really require access to any secret when computing manifest diff (even if that involves calling a `./gradlew process{variant}Manifest` task)… let's test
| echo "--- :closed_lock_with_key: Installing Secrets" | ||
| bundle exec fastlane run configure_apply | ||
|
|
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.
Having the repo git-crypt-unlocked during the branch dance that is done internally by comment_with_manifest_diff caused Your local changes to the following files would be overwritten by checkoutissues, especially if the git-crypt'd files listed in .gitattributes on the HEAD branch are not the same as the ones in the BASE branch1
Since we don't need any secret in practice to generate the manifest and call process{variant}Manifest, the solution is simple: just don't bother unlocking the repo's secrets for that task.
A better long-term solution to make comment_with_manifest_diff more resilient to situations like this would be to make it use git worktree instead of switching branches in-place:
- Generate base manifest:
git worktree add $TMP_DIR_FOR_BASE $BASE_BRANCH && cd $TMP_DIR_FOR_BASEthen run./gradlew process{variant}Manifestthere - Generate head manifest:
cd $CHECKOUT_DIR && rm $TMP_DIR_FOR_BASE && git worktree prunethen run./gradlew process{variant}Manifestthere
That way each checkout is done in independent folders, eliminating the risk of conflicts during the branch dance.
Footnotes
-
like will be the case during that transition to
git-crypt, or when we'll add a new secret file, especially if that secret file previously existed unencrypted in the BASE branch as an example file for external contributors I think? ↩
| export CI_TOOLKIT="automattic/a8c-ci-toolkit#5.4.0" | ||
| # "git-crypt-unlock" branch / https://github.com/Automattic/a8c-ci-toolkit-buildkite-plugin/pull/195 | ||
| export CI_TOOLKIT="automattic/a8c-ci-toolkit#0a3f10921096cee57c18ac5667fc64c1aaad4a7d" |
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.
🎗️ TODO: Revert back to pointing to a tag version once Automattic/a8c-ci-toolkit-buildkite-plugin#195 is merged and we have an official new version of the ci-toolkit
Generated by 🚫 Danger |
wzieba
left a comment
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 real migration won't require devs to clone the repo from scratch; this is just for the testing steps of this PR
Hm, I don't know why exactly, but ~/woocommerce-android/.configure-files/firebase.secrets.json is not respected in .gitignore on this branch.
So, as a result, I could by mistake include the firebase.secrets.json in my git commit. To reproduce:
gco trunkbundle exec fastlane run configure_applygco AINFRA-882-adopt-git-cryptgit status -u
| if (!googleServicesFile.exists() || isFileEncrypted(googleServicesFile)) { | ||
| tasks.copyGoogleServicesExampleFile.copy() | ||
| } |
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.
If google-services.json is encrypted, we'll copy the example file. Then why do we require to
cp WooCommerce/google-services.json-example WooCommerce/google-services.json(to replace that encrypted file with placeholder content)
in the docs?
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.
Because I updated the docs before first, then later realized I had to update the .gradle file to make CI work… and didn't get back to review the docs again after doing the .gradle change 😅
Good point then, we should indeed remove that extra step from the docs.
|
|
||
| If you are a developer working at Automattic, ensure you followed those instructions once after cloning the repo: | ||
| 1. Make sure you have `git-crypt` installed (`brew install git-crypt`) | ||
| 1. Search for "WooCommerce Android git-crypt encryption key" in our Secret Store, and copy the Base64 value in your clipboard |
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.
nit: I wonder, is it okay to provide a direct link to Secret Store? 🤔
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.
Yeah I hesistated on this too. It's probably OK I guess because it's just a link that won't be accessible by anyone outside Automattic, and those links just contain ?id=<number> so it doesn't really reveal anything in the link URL either…
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.
Yes, I also had second thoughts before suggesting this, but actually our security doesn't rely on obscurity of a url. I think it's fine to share the link here, MC requires multpile security measures anyway to get anything from it.
This is a very good and important point, thanks for raising it! This PR indeed removed those files from |
Closes: AINFRA-1533
What
This PR migrates the repo to use
git-cryptinstead ofconfigure_apply, so that the usage of secrets in the repo gets easier and more transparent for developers.How
.configureand.configure-files/*.encfiles.configureas encrypted files in the repo instead, by also adding their path as entries in the.gitattributeswithfilter=git-crypt diff=git-crypt—so they get encrypted bygit-crypton push.gradlefiles andFastfileto account for new file paths.gradlecode to account for the fact that now the files are present (but encrypted) after cloning the repo—as opposed to being absent when we didn't runconfigure_applyin the old way.bundle exec fastlane run configure_applyin.buildkite/*commands—and calls toconfigure_apply(force: true)inFastfile—with calls to.buildkite/commands/git-crypt-unlock.sh, and bumpci-toolkitplugin to point to Addgit-cryptwrapper Automattic/a8c-ci-toolkit-buildkite-plugin#195Note
ℹ️ About the git-crypt helper from ci-toolkit
Currently, none of our CI agent have
git-cryptpre-installed. Besides, it might get tricky to have agit-cryptbinary for all needed architectures/platforms; in particular, compilinggit-cryptfor Windows seems tricky (and not that well documented) and the author admits the tool hasn't been tested as thoroughly on Windows.To account for that,
ci-toolkitprovides agit-cryptwrapper script, that takes care of runninggit-cryptfrom within a docker container. This involves some sugarcoating (handle.git/objects/info/alternatesused by git-mirrors on CI, etc) which is ultimately hidden to the caller by that wrapper script, to allow you to call thisgit-cryptwrapper exactly the same way you'd call the real one.Future Directions
Before merging:
a8c-ci-toolkit-buildkite-plugin's.buildkite/pipeline.ymlso that itdocker buildanddocker pushthegit-cryptdocker image to our AWS ECR, so that CI agents won't have to rebuild the image from scratch each.git-cryptwrapper Automattic/a8c-ci-toolkit-buildkite-plugin#195, create a newci-toolkitversion/tag, then update this PR'sshared-pipeline-varsto point to itIn the longer term:
git-cryptbinary directly into our various CI agents1, so that when they'll callgit-cryptthe pre-installed binary that appears earlier in the$PATHwould then supersede the wrapper script fromci-toolkit(thus bypassing the need for wrapping the execution insidedocker run)Merge timing
Important
Do not merge this PR until (1) we have all the documentation / FAQ ready for all devs to follow in FG and (2) we have validated similar PRs in other repos—especially ones using macOS/Windows and Tumblr CI agents—work too. Indeed, if the adoption of
git-cryptworks well in macOS and in Android agents but doesn't work on some other agents (like Windows instances or Tumblr k8s agents), this is going to be a blocker for adoption after all.Test Steps
General check
WooCommerce/google-services.jsonWooCommerce/upload.jksdebug.keystorefirebase.secrets.jsongoogle-upload-credentials.jsonsecrets.propertiessentry.properties*.gradlefiles to reflect the new setup are covered by this PR (path updates to.propertiesor keystore files, code updates around logic that was based on if a secret file exists or not, …)Follow the
README.mdinstructions as an Automatticiangit-crypt unlock <(pbpaste | base64 -d)at the root of your new clone's directorysecrets.propertiesin clear nowgoogle-services.jsonis taken into account, etc)Note
ℹ️ The real migration won't require devs to clone the repo from scratch; this is just for the testing steps of this PR
Above I suggest to test this scenario in a fresh clone of the repo rather than your everyday working copy, especially to avoid risking to leave your git repo in a state that is setup for
git-cryptwhile you were just testing and the PR is not merged yet.In practice, once the PR is merged in
trunk, devs won't need to clone the repo fresh to migrate togit-cryptthough.They will just have to run
git-crypt unlock <(pbpaste | base64 -d)on their existing working copy and nothing else.Though at some point I'd still highly recommend for them also get rid of the old files that were installed by their previous setup with
configure(rm -rf ~/.configure/woocommerce-androidandgit clean -dxi -e .DS_Store -e .idea -e local.properties), to avoid confusion and risking relying on obsolete files.Follow the
README.mdinstructions as an external contributorsecrets.propertiesshow as encrypted garbagedefaults.propertiesto add the relevant values forwp.oauth.*WooCommerce/google-services.jsonencrypted file withWooCommerce/google-services.json-exampleFootnotes
At least the Mac Minis and the custom AMI for
android; might be more cumbersome for Windows as runninggit-crypt'smaketo compile it for Windows is quite more involved and not well documented ↩