Automated deployment using a CI/CD pipeline
You can build a continuous integration and continuous deployment (CI/CD) pipeline to automate deployments to production. You can also use these pipelines to run automated tests before deploying.
You can use any CI/CD platform to build a pipeline, such as GitHub Actions, CircleCI, GitLab, or Jenkins.
Using ggt
in a CI/CD pipeline
To set up a CI/CD pipeline for your Gadget app, you need to:
- Use source control to manage your Gadget project(s).
- Generate a CLI token for your app used to authenticate
ggt
. - Deploy changes to production using
ggt deploy
.
ggt deploy
will automatically run ggt push
under the hood if the local filesystem, which is your test runner and git branch, does not
match the hosted environment. This is so the latest code and configuration on your specified git branch will always be deployed to
production.
Using a CLI token to run ggt deploy
You need to provide a CLI token so that ggt
can make authenticated requests to your Gadget app. Read our docs on generating a token here.
Once the CLI token has been generated, it needs to be stored as a secret in the CI platform you are using. After storing your CLI token as a secret, the token can be safely used in your pipeline to run authenticated ggt
commands.
Here is how you can pass a CLI token to ggt
in a GitHub Action:
using a CLI token to deploy in a CI/CD pipelineyml1- uses: actions/checkout@v42- name: Install ggt # first, install ggt in the test runner environment3 run: |4 npm install -g ggt@latest5 ggt version6 shell: bash78- name: Deploy to production # deploy to production for the passed in app and environment9 run: |10 ggt deploy --app=<your-app-name> --env=<your-environment> --force --allow-unknown-directory11 shell: bash12 env:13 GGT_TOKEN: ${{ secrets.GGT_TOKEN }}
The --allow-unknown-directory
flag is required when an app's .gadget
folder has not been pulled into your test runner before running
ggt deploy
. This flag allow you to deploy to production without a .gadget/sync.json
file.
The --force
flag is used to overwrite the current hosted environment with whatever currently exists in the git branch, ensuring that the
lasted code and configuration is deployed.
Example: Use a pre-built GitHub Action
Here is an example running ggt deploy
using the pre-built gadget-inc/ggt-deploy-action@v1
.
ggt-deploy-action
will automatically install ggt
and run ggt deploy
with the passed in options.
- Generate a CLI token in Gadget.
- Go to your GitHub repository's Settings, then find the Secrets section. Add a new secret named
GGT_TOKEN
and paste your CLI token as the value. This step ensures that your token is securely stored and accessible in your GitHub Actions workflow. - In your Gadget app, create a
.github/workflows
directory. Inside, you'll create aYAML
file for your workflow. - In your
YAML
workflow file, paste the token as shown below in the config steps of your Github Action.
action.ymlyaml1name: CI/CD Pipeline23on:4 push:5 branches:6 - main # or any other branch you want to deploy from78jobs:9 deploy:10 steps:11 - name: Checkout the current repository12 uses: actions/checkout@v413 - name: Deploy to Gadget Production14 uses: gadget-inc/ggt-deploy-action@v115 with:16 app: '<your-app-name>'17 environment: '<your-environment>' # The environment you are deploying to production18 token: ${{ secrets.GGT_TOKEN }} # Add your CLI token19 allow-issues: 'false' # Optionally, continue deployment even if there are issues
This action will be run automatically every time you push to the main
branch. It will:
- install
ggt
into your test runner environment - take the latest code and configurations from your git branch and push it to the specified Gadget environment
- deploy that environment to production
Automated testing
You can also run automated tests as part of a CI/CD pipeline. This means you run tests between pushing your changes from git to Gadget, and deploying.
To run automated tests in a CI/CD pipeline, you need to:
- Use source control to manage your Gadget project(s).
- Generate a CLI token for your app used to authenticate
ggt
. - Update a Gadget environment with the latest code and configuration from your git branch using
ggt push
:
sample ggt push commandggt push --app=<your-app-name> --env=<your-environment> --force --allow-unknown-directory
- Run your tests against the updated environment. A
ggt pull
may be required to bring in files not maintained in source control if you are running tests using a Gadget API client. - Deploy changes to production using
ggt deploy
.
Example CI/CD with tests: GitHub Actions
Here is an example of pushing all code to a staging environment in Gadget, then running a unit test suite in a GitHub Action:
a GitHub Action that pushing to a "staging" environment, runs tests, and deploysyml1name: deploy to prod23on:4 push:5 branches: [main]67env:8 GADGET_ENV: staging9 GADGET_TEST_API_KEY: ${{ secrets.GADGET_TEST_API_KEY }}1011jobs:12 push: # first job, push changes from git to a "staging" environment13 runs-on: ubuntu-latest14 steps:15 - uses: actions/checkout@v41617 - name: Install ggt18 run: |19 npm install -g ggt20 ggt version21 shell: bash2223 - name: Push code to test/CI environment24 run: |25 ggt push --app=<your-app-name> --env=staging --force --allow-unknown-directory26 shell: bash27 env:28 GGT_TOKEN: ${{ secrets.GGT_TOKEN }}2930 test: # second job, run automated tests31 runs-on: ubuntu-latest32 needs: push33 steps:34 - uses: actions/checkout@v43536 - name: Create env file # a .env file is required for an API key (stored as a secret)37 run: |38 touch .env39 echo GADGET_TEST_API_KEY="$GADGET_TEST_API_KEY" >> .env40 echo GADGET_ENV="$GADGET_ENV" >> .env4142 - name: Install ggt # each job is a fresh environment, so ggt must be reinstalled43 run: |44 npm install -g ggt45 ggt version46 shell: bash4748 - name: Pull client files into env # pull .gadget folder into test runner49 run: |50 ggt pull --app=<your-app-name> --env=staging --force --allow-unknown-directory51 shell: bash52 env:53 GGT_TOKEN: ${{ secrets.GGT_TOKEN }}5455 - name: Install dependencies56 run: yarn --frozen-lockfile5758 - name: Run tests59 run: yarn test6061 deploy: # final job, deploy staging to production62 runs-on: ubuntu-latest63 needs: test64 steps:65 - uses: actions/checkout@v46667 - name: Install ggt68 run: |69 npm install -g ggt70 ggt version71 shell: bash7273 - name: Deploy to production # run ggt deploy to deploy changes from staging to production74 run: |75 ggt deploy --app=<your-app-name> --env=staging --force --allow-unknown-directory --allow-problems76 shell: bash77 env:78 GGT_TOKEN: ${{ secrets.GGT_TOKEN }}
In this example, a CLI token (GGT_TOKEN
) and an API key for the staging environment (GADGET_TEST_API_KEY
) are stored as secrets in GitHub.
This could also be compressed into a single job and ggt
would only need to be installed once.