USACE / instrumentation

Instrumentation project issue tracking and project planning
MIT License
4 stars 1 forks source link

Discussion - Deployment Strategy (UI) #90

Closed KevinJJackson closed 11 months ago

KevinJJackson commented 3 years ago

@brettpalmberg and I discussed options for deploying the application to multiple environments (dev, test and prod). Below is an option utilizing GitHub tags and environment variables.

CRA allows us to use custom environment variables to change the configuration of the application at build time https://create-react-app.dev/docs/adding-custom-environment-variables/. We can use this to set separate API urls for each build (dev API for dev UI, etc...). We can also use these as a form of feature flag for the idea behind having a banner on the development/test site informing users that the data they are using is not the real production data. To set these variables, we would need to incorporate them into the UI build for each environment and as such, would need to introduce a different build for each environment possibly using GitHub actions to do so.

The workflow would then look like:

  1. developer merges code from branch -> develop. *Ensure merge strategy is Squash and Merge to avoid multiple builds being triggered and to keep branch history clean
  2. GitHub action gets triggered setting the appropriate variables for the dev environment, builds and deploys to dev
  3. Upon successful deployment to dev, GitHub action gets triggered setting the appropriate variables for the test environment, builds and deploys to test (This step could be completed simultaneously with step 2, if we don't want to do dev verification before it hits test)
  4. Do any necessary verification of the dev/test environment and determine readiness for prod.
  5. When ready to start production build, cut a new tag. This tag will be our production version. When a new tag is cut, the production GitHub action will be triggered, setting the environment variables necessary for prod, builds and deploys the new build to production.

This issue is open for discussion and is just an option of a way forward.

cc: @adamscarberry, @brettpalmberg

brettpalmberg commented 3 years ago

This looks good @KevinJJackson - I like the use of tags and the simplicity. A few ideas for discussion:

I think we may want to be able to hotfix stable (i.e. production) via a very surgical branch to address a specific issue in stable (even if development has continued on branch develop). Would this mean we should introduce a branch called stable?

I think this suggestion may be leading us down the road of using a simple version of Gitlab Flow with Environment Branches, where we would have separate branches by environment. i.e. develop, test, and stable.

Although this adds more branches, it would make it simple to control what goes to stable by doing a build and deploy on any commit to branch stable.

KevinJJackson commented 3 years ago

I think we may want to be able to hotfix stable (i.e. production) via a very surgical branch to address a specific issue in stable (even if development has continued on branch develop). Would this mean we should introduce a branch called stable?

This could lead to problems with back-patching develop, but I do see benefit of having a separate branch specifically for production. I think having a separate test branch is unnecessary as any issues found on that environment would stop a push to production and require a new dev fix anyway.

brettpalmberg commented 3 years ago

This sounds good - agree we can and should forego a test branch at this time. I think this means the users evaluating the code we're proposing for stable will see code based on the last commit to develop, rather than deploying whatever release was ready for test to a dedicated test environment and letting development branch continue to receive new commits. This should be ok at this time and we can re-evaluate at a later date.

Recommend we move forward with two branches - a branch named develop and a branch called stable.

All commits to develop should result in a new build and deploy to the development environment. What would we like to use as a strategy for commits (squash/merge/etc.) and tags for develop and stable?

Note: Would like to call the branch stable (rather than production) as we're still in development pre-v1.0 release.

KevinJJackson commented 3 years ago

Agreed stable makes more sense at this state than production.

As for tagging and merging, I think it'd make sense to tag as we merge to each branch (preferably squash and merge strategy). This would cause our branches to look something like this (each x is a single commit in the history):

   stable    ----------X
  develop    --x-----x-^
feature-1    -x^
feature-2    -x--x--x^

Each commit to develop could be automatically tagged as a release candidate, as, especially in an agile environment, every commit should be buildable and deployable. This would also translate into each develop commit needing to increase the version of the product.


Potential Workflow: Current App version: 0.4.0

brettpalmberg commented 3 years ago

I think this looks great and really appreciate the detailed write-up @KevinJJackson . I think this will be helpful for the whole team as a reference.

Squashing and merging the commits into develop, the dev knows this is a large change and increases the version number to 0.5.0

Can you help define our M.O. and the commands we should run at the command line before commit for the ui? Thinking we should use generally follow semantic versioning without going overboard and use npm-version. Thoughts ?

cc @adamscarberry @jeffsuperglide

KevinJJackson commented 3 years ago

Definitely agree on semantic versioning. I haven't used the npm-version package before, but it seems straightforward enough. Looks like we could run that command after the merge to develop to do the version bump and tag cut?

Might looks something like this:

  1. Dev creates feature branch off of latest develop

    git checkout develop
    git pull
    git checkout -b 'feature/new-feature'
  2. After a few commits, the dev validates the build and pushes the new branch to remote to open a PR.

    npm run build
    git push --set-upstream origin feature/new-feature
  3. The PR is approved. The dev squashes and merges into develop using the GitHub UI. Don't forget to delete your branch!

  4. The dev pulls their new changes into their local repo and runs the new version script setting major, minor, or patch as the version param and with a concise message about the change. This will create a new tag version for use in Step 5

    git checkout develop
    git pull
    npm version minor -m 'Added new feature'
  5. The dev will then need to push the new commit and the created tag to the remote repository (replace <new_tag_version> with the tag created in Step 4

    git push
    git push origin <new_tag_version>
brettpalmberg commented 3 years ago

I think I may have nudged us down the wrong road if npm-version is a separate npm dependency. Let's stick with the built-in commands: npm version major or npm version minor or npm version patch.

We'll do something like this (same as what you showed above): npm version minor -m "minor bugfix". This should bump the version in package.json, create a commit, and create a tag. Perfect! (Image below)

image

brettpalmberg commented 3 years ago

Two new buckets for deploy via Github Actions have been created. Names are below for reference.

KevinJJackson commented 3 years ago

Cool, that works for me. the only difference with that is you will have to manually push the tag you created to remote. so in your example above that is as easy as:

git push origin v2.2.1

Edit: Updated my comment above to keep everything in one place.

brettpalmberg commented 3 years ago

Investigating now - would like to find a way for developers to not have to push to develop directly ever.

KevinJJackson commented 3 years ago

Agreed, I found this (https://github.com/marketplace/actions/automated-version-bump) while doing some research and it seems like we could use this to bump the version? Essentially does a keyword search on the commit to see what to bump.

could make it so a commit title patch/new-patch bumps a patch version or feature/new-feature bumps minor etc...

dennisgsmith commented 11 months ago

Since migrating to GovCloud, CI/CD for UI and API needs to be reconfigured.