The goal of this lab is to show you how you could automate the deployment of the app to a specific environment, e.g. staging or production.
Note: this lab builds upon the results of the previous labs
In previous stages of the pipeline we make sure the latest changes were integrated, the test were passing and the application is built and package. That gives us enough confident that we can deploy the latest version of the application to an environment.
Think about it, when do the latest code changes start delivering value? Is it when they are tested and the application is built or is it when they are deployed and released to the end users?
This stage of the pipeline is a bit more complicated. So far we were running commands only in the Github Actions worker machines. To automate a deployment we need to trigger an action in an external service, the one providing the deployment environment. We need to authenticate with the service where we will deploy our app.
For the scope of this tutorial, we will use Vercel. You can think of Vercel like a free server where you can expose your app to real users. If you don't have a Vercel account, it is fine! No worries. You can go for option 1 in this lab where we simulate a deployment.
"Deploy the same way to every environment—including development. This way, we test the deployment process many, many times before it gets to production, and again, we can eliminate it as the source of any problems." -- by continuousdelivery.com
Let's start by adding a new build tasks to our package.json file. This task automates the process of performing a deployment to a specific environment. Your script section in the package.json file should look like:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test:unit": "jest --ci",
"deploy:simulate": "../scripts/simulate-deployment.sh"
},
We added a new npm task, deploy:simulate, that calls a script that simulates a deployment and tells when the deployment is completed. Let's try to execute the automated deployment process locally and see what happens.
cd modern-web-app
npm run deploy:simulate -- production
So far so good, we automated our deployment process so that we can run it from our local environment. Next step is to perform the automated deployment as part of the pipeline. Lets add a new job that allow us to deploy our modern web app to an environment that we will call production. Lets add a new job:
jobs:
[....]
deploy-prod:
name: Deploy to prod
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Deploy with Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v1
with:
node-version: ${{ env.NODE_VERSION }}
- name: Download build artifact
uses: actions/download-artifact@v3
with:
name: modern-web-app-${{ github.sha }}
path: artifact_to_deploy
- name: Deploy to prod environment
run: |
npm run deploy:simulate -- production
Once the changes are commited and pushed, the pipeline should run automatically as it is especified to run on push.
git add .
git commit -m "Add deployment stage to the CI/CD pipeline"
git push
Lets add a new job that allow us to deploy our modern web app to an environment that we will call production.
jobs:
[....]
deploy-prod:
name: Deploy to prod
needs: check-performance
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Deploy with Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v1
with:
node-version: ${{ env.NODE_VERSION }}
- name: Deploy to prod environment
run: |
npm i -g vercel
vercel --token "$VERCEL_TOKEN" --prod
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
What are the differences between continuous integration vs. delivery vs. deployment?
- Read the instructions
- Add the deploy:simulate tasks in the NPM scripts declaration
- Add the automated deployment job to the CD pipeline
- Push the changes and check the pipeline logs in the Actions tab
- Answer this question: Is the pipeline implementing continuous delivery or continuous deployment?