Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 23 additions & 63 deletions .github/workflows/gadget-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ on:
description: "Deployment action to perform: 'push' (push to environment) or 'deploy' (deploy to production)"
type: string
required: true
test:
description: "Boolean to check if run tests"
type: boolean
default: false

# Backport Configuration
create-backport-pr:
Expand All @@ -38,20 +34,17 @@ on:
default: "staging"

secrets:
gadget-api-token:
description: "Gadget API token"
ggt-cli-token:
description: "GGT cli token"
required: true
gadget-test-api-key:
description: "Gadget Test API key for running tests"
required: false

jobs:
push:
name: 🫸 Push to Gadget
runs-on: ubuntu-latest
if: inputs.action == 'push'
env:
GGT_TOKEN: ${{ secrets.gadget-api-token }}
GGT_TOKEN: ${{ secrets.ggt-cli-token }}
outputs:
push-environment-status: ${{ steps.push-environment.outcome }}
steps:
Expand Down Expand Up @@ -85,63 +78,12 @@ jobs:
INPUTS_APP_NAME: ${{ inputs.app-name }}
INPUTS_ENVIRONMENT_NAME: ${{ inputs.environment-name }}

test:
name: 🧪 Test from Gadget
runs-on: ubuntu-latest
if: inputs.test == true && inputs.action == 'push'
needs: push
env:
GGT_TOKEN: ${{ secrets.gadget-api-token }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
with:
persist-credentials: false

- name: Install ggt
run: |
npm install -g ggt
ggt version

- name: Pull client files into env # pull .gadget folder into test runner
working-directory: ${{ inputs.working-directory }}
run: |
ggt pull \
--app=${INPUTS_APP_NAME} \
--env=${INPUTS_ENVIRONMENT_NAME} \
--force --allow-unknown-directory
env:
INPUTS_APP_NAME: ${{ inputs.app-name }}
INPUTS_ENVIRONMENT_NAME: ${{ inputs.environment-name }}

- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e #v6.4.0
with:
node-version-file: ${{ inputs.working-directory }}/.nvmrc
cache: yarn
cache-dependency-path: ${{ inputs.working-directory }}/yarn.lock

- name: Install safe-chain
run: |
SAFE_CHAIN_URL="https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh"
curl -fsSL "$SAFE_CHAIN_URL" | sh -s -- --ci

- name: Install dependencies
working-directory: ${{ inputs.working-directory }}
run: yarn --frozen-lockfile

- name: Run tests
working-directory: ${{ inputs.working-directory }}
env:
GADGET_TEST_API_KEY: ${{ secrets.gadget-test-api-key }}
GADGET_ENV: ${{ inputs.environment-name }}
run: yarn test

deploy:
name: 🚀 Deploying Gadget
runs-on: ubuntu-latest
if: inputs.action == 'deploy'
env:
GGT_TOKEN: ${{ secrets.gadget-api-token }}
GGT_TOKEN: ${{ secrets.ggt-cli-token }}
INPUTS_APP_NAME: ${{ inputs.app-name }}
TEMP_ENV_NAME: deploy-${{ github.run_id }}
steps:
Expand All @@ -159,13 +101,31 @@ jobs:
ggt env create ${TEMP_ENV_NAME} \
--app ${INPUTS_APP_NAME}

- name: Wait for environment provisioning to settle
# `ggt env create` returns as soon as the environment record exists, but Gadget
# keeps copying files in the background. Pushing immediately can cause
# "Your environment's files have changed since we last checked." error.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no way to make the command wait for it to be complete or some way to actually tell if it's complete? An arbitrary sleep isn't ideal.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tmthrgd-aligent as documented, ggt env create returns as soon as the environment record exists. It's an async command. You either wait then push in the pipeline like this or write a custom script which do the same thing. I would prefer do it in the pipeline for clarity.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kai-nguyen-aligent Right I get that it's async, what I'm asking is do they really not provide any way or any command, any API or any flag to actually wait for it to complete?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tmthrgd-aligent Unfortunately not.

run: sleep 30

- name: Push code to temp Gadget environment
working-directory: ${{ inputs.working-directory }}
# Retry on top of the delay: a busy backend can still be mid-provisioning past the
# sleep, and ggt's own error message for this race is literally "please re-run ggt push".
run: |
ggt push \
attempt=1
until ggt push \
--app=${INPUTS_APP_NAME} \
--env=${TEMP_ENV_NAME} \
--force --allow-unknown-directory
do
if [ "$attempt" -ge 3 ]; then
echo "ggt push failed after $attempt attempts"
exit 1
fi
echo "ggt push failed (attempt $attempt), retrying in 10s..."
sleep 10
attempt=$((attempt+1))
done

- name: Deploy (promote) to Production environment in Gadget
working-directory: ${{ inputs.working-directory }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ A collection of GitHub action workflows. Built using the [reusable workflows](ht
| [AWS CDK](docs/aws-cdk.md) | Multi-environment infrastructure synthesis, diffs and deployments with automatic package manager detection |
| [Changeset Check](docs/changeset-check.md) | Advisory PR comments when changesets are missing for affected packages |
| [Changeset Release](docs/changeset-release.md) | Automated package versioning and publishing with Changesets |
| [Gadget App Deployment](docs/gadget-deploy.md) | Gadget app deployment with push, test, and production deployment stages |
| [Gadget App Deployment](docs/gadget-deploy.md) | Gadget app deployment with push and production deployment stages |
| [Magento Cloud Deployment](docs/magento-cloud-deploy.md) | Magento Cloud deployment with optional NewRelic monitoring and CST reporting |
| [Node Pull Request Checks](docs/node-pr.md) | Pull request quality checks for Node.js projects |
| [Nx Serverless Deployment](docs/nx-serverless-deployment.md) | Serverless deployment workflow for Nx monorepos |
Expand Down
37 changes: 5 additions & 32 deletions docs/gadget-deploy.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
# Gadget App Deployment

A comprehensive Gadget app deployment workflow supporting push, test, and production deployment stages with multi-environment management.
A comprehensive Gadget app deployment workflow supporting push and production deployment stages with multi-environment management.

#### **Features**
- **Custom-environment support**: Support for custom development environment name
- **Conditional automated testing**: Automatic test execution controlled by boolean flag
- **Conditional deployment**: Production deployment controlled by boolean flag
- **Temporary environment deployment**: Production deploys create a temporary Gadget environment, push code to it, promote to production, and clean up automatically
- **Force push capabilities**: Ensures code synchronization with `--force` flag
- **Gadget CLI integration**: Uses `ggt` CLI tool for all operations
- **Test validation**: Runs full test suite before production deployment
- **Automatic backporting**: Optional PR creation to backport changes to staging branch

#### **Inputs**
Expand All @@ -21,16 +19,14 @@ A comprehensive Gadget app deployment workflow supporting push, test, and produc
| environment-name | ⚠️ | string | | Gadget environment name (required when `action: push`) |
| **Deployment Control** |
| action | ✅ | string | | Deployment action: `push` (push to environment) or `deploy` (deploy to production) |
| test | ❌ | boolean | false | Enable testing on development environment |
| **Backport Configuration** |
| create-backport-pr | ❌ | boolean | false | Create a backport PR after deployment |
| backport-target-branch | ❌ | string | staging | Target branch for backport PR |

#### **Secrets**
| Name | Required | Description |
|------|----------|-------------|
| gadget-api-token | ✅ | Gadget API authentication token |
| gadget-test-api-key | ❌ | Gadget Test API key (required when `test: true`) |
| ggt-cli-token | ✅ | Gadget API authentication token |

#### **Outputs**
| Name | Description |
Expand Down Expand Up @@ -59,7 +55,7 @@ jobs:
environment-name: staging
action: push
secrets:
gadget-api-token: ${{ secrets.GADGET_API_TOKEN }}
ggt-cli-token: ${{ secrets.GGT_CLI_TOKEN }}
```

**Push to custom Environment Name:**
Expand All @@ -80,30 +76,7 @@ jobs:
environment-name: development
action: push
secrets:
gadget-api-token: ${{ secrets.GADGET_API_TOKEN }}
```

**Push with Testing:**
```yaml
on:
push:
branches:
- staging

...

jobs:
push-and-test:
uses: aligent/workflows/.github/workflows/gadget-deploy.yml@main
with:
app-name: my-gadget-app
working-directory: apps/gadget-app
environment-name: staging
action: push
test: true
secrets:
gadget-api-token: ${{ secrets.GADGET_API_TOKEN }}
gadget-test-api-key: ${{ secrets.GADGET_TEST_API_KEY }}
ggt-cli-token: ${{ secrets.GGT_CLI_TOKEN }}
```

**Production deployment from Release:**
Expand All @@ -122,7 +95,7 @@ jobs:
working-directory: apps/gadget-app
action: deploy
secrets:
gadget-api-token: ${{ secrets.GADGET_API_TOKEN }}
ggt-cli-token: ${{ secrets.GGT_CLI_TOKEN }}
```

When `action: deploy`, the workflow uses a temporary environment strategy to safely promote code to production:
Expand Down