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:

  1. Use source control to manage your Gadget project(s).
  2. Generate a CLI token for your app used to authenticate ggt.
  3. 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 pipeline
yml
1- name: Install ggt # first, install ggt in the test runner environment
2 run: |
3 npm install -g ggt@latest
4 ggt version
5 shell: bash
6
7- name: Deploy to production # deploy to production for the passed in app and environment
8 run: |
9 ggt deploy --app=<your-app-name> --env=<your-environment> --force --allow-unknown-directory
10 shell: bash
11 env:
12 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.

  1. Generate a CLI token in Gadget.
  2. 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.
  3. In your Gadget app, create a .github/workflows directory. Inside, you'll create a YAML file for your workflow.
  4. In your YAML workflow file, paste the token as shown below in the config steps of your Github Action.
action.yml
yaml
1name: CI/CD Pipeline
2
3on:
4 push:
5 branches:
6 - main # or any other branch you want to deploy from
7
8jobs:
9 deploy:
10 steps:
11 - name: Checkout the current repository
12 uses: actions/checkout@v4
13 - name: Deploy to Gadget Production
14 uses: gadget-inc/ggt-deploy-action@v1
15 with:
16 app: '<your-app-name>'
17 environment: '<your-environment>' # The environment you are deploying to production
18 token: ${{ secrets.GGT_TOKEN }} # Add your CLI token
19 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:

  1. Use source control to manage your Gadget project(s).
  2. Generate a CLI token for your app used to authenticate ggt.
  3. Update a Gadget environment with the latest code and configuration from your git branch using ggt push:
sample ggt push command
ggt push --app=<your-app-name> --env=<your-environment> --force --allow-unknown-directory
  1. 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.
  2. 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 deploys
yml
1name: deploy to prod
2
3on:
4 push:
5 branches: [main]
6
7env:
8 GADGET_ENV: staging
9 GADGET_TEST_API_KEY: ${{ secrets.GADGET_TEST_API_KEY }}
10
11jobs:
12 push: # first job, push changes from git to a "staging" environment
13 runs-on: ubuntu-latest
14 steps:
15 - uses: actions/checkout@v4
16
17 - name: Install ggt
18 run: |
19 npm install -g ggt
20 ggt version
21 shell: bash
22
23 - name: Push code to test/CI environment
24 run: |
25 ggt push --app=<your-app-name> --env=staging --force --allow-unknown-directory
26 shell: bash
27 env:
28 GGT_TOKEN: ${{ secrets.GGT_TOKEN }}
29
30 test: # second job, run automated tests
31 runs-on: ubuntu-latest
32 needs: push
33 steps:
34 - uses: actions/checkout@v4
35
36 - name: Create env file # a .env file is required for an API key (stored as a secret)
37 run: |
38 touch .env
39 echo GADGET_TEST_API_KEY="$GADGET_TEST_API_KEY" >> .env
40 echo GADGET_ENV="$GADGET_ENV" >> .env
41
42 - name: Install ggt # each job is a fresh environment, so ggt must be reinstalled
43 run: |
44 npm install -g ggt
45 ggt version
46 shell: bash
47
48 - name: Pull client files into env # pull .gadget folder into test runner
49 run: |
50 ggt pull --app=<your-app-name> --env=staging --force --allow-unknown-directory
51 shell: bash
52 env:
53 GGT_TOKEN: ${{ secrets.GGT_TOKEN }}
54
55 - name: Install dependencies
56 run: yarn --frozen-lockfile
57
58 - name: Run tests
59 run: yarn test
60
61 deploy: # final job, deploy staging to production
62 runs-on: ubuntu-latest
63 needs: test
64 steps:
65 - uses: actions/checkout@v4
66
67 - name: Install ggt
68 run: |
69 npm install -g ggt
70 ggt version
71 shell: bash
72
73 - name: Deploy to production # run ggt deploy to deploy changes from staging to production
74 run: |
75 ggt deploy --app=<your-app-name> --env=staging --force --allow-unknown-directory --allow-problems
76 shell: bash
77 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.