The awsplace project operates dual CI/CD pipelines: GitHub Actions (.github/workflows/deploy.yml) and GitLab CI (.gitlab-ci.yml). Both pipelines serve as automated gatekeepers — no code reaches production without passing every validation stage.
The GitHub Actions workflow is named “Test & Deploy” and is triggered on:
on:
push:
branches: [main]
tags: ['*']
pull_request:
branches: [main]
The deployment job (deploy) has a strict needs dependency chain — it only runs after ALL test jobs succeed:
deploy:
needs:
[test-lambda, test-go-unit, test-go-postgres, test-go-ministack, test-cdk, publish-raftdb-image]
if: github.ref == 'refs/heads/main'
This means a failure in any of the 6 prerequisite jobs will block deployment entirely.
Before running cdk deploy, the pipeline executes critical validation scripts:
bash scripts/validate-deploy-env.sh
This script (tested by deploy-config.test.cjs) ensures:
bash scripts/prepare-cloudformation-deploy.sh AwsplaceStack
This script handles stuck CloudFormation stacks:
bash scripts/check-websocket-origin.mjs
Both GitHub and GitLab pipelines verify that the WebSocket origin URL matches the deployment domain, preventing CORS/origin mismatch issues.
Once all validations pass, the actual deployment happens:
- name: CDK deploy
env:
SESSION_SECRET: ${{ secrets.SESSION_SECRET }}
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
HOSTED_ZONE_ID: ${{ secrets.HOSTED_ZONE_ID }}
DOMAIN_NAME: ${{ secrets.DOMAIN_NAME }}
ECS_IMAGE_TAG: ${{ github.sha }}
RAFTDB_IMAGE_DIGEST: ${{ needs.publish-raftdb-image.outputs.digest }}
run: |
bash scripts/validate-deploy-env.sh
bash scripts/prepare-cloudformation-deploy.sh AwsplaceStack
cd cdk
npm ci && npm run build
npx cdk deploy --require-approval never --no-strict --all --import-existing-resources
Key flags:
After CDK deploys the infrastructure, the pipeline:
The RaftDB image follows a rigorous chain of custody:
# Re-verify after ECR publication
- name: Pull digest into a clean local image cache
run: |
docker pull "${ECR_URI}@${IMAGE_DIGEST}"
bash raftdb/test/container_contract_test.sh "${ECR_URI}@${IMAGE_DIGEST}"
bash raftdb/test/migration_runtime_contract_test.sh "${ECR_URI}@${IMAGE_DIGEST}"
The .gitlab-ci.yml file (26,685 bytes) mirrors the GitHub Actions workflow with equivalent validation stages. The deployment contract tests (deployment-contract.test.cjs) explicitly verify that both pipelines contain the same critical commands:
test('GitLab and GitHub publish and deploy through the shared ECR contract', () => {
for (const workflow of [gitlab, github]) {
expect(workflow).toContain('scripts/push-ecs-image.sh');
expect(workflow).toContain('ECS_IMAGE_TAG');
expect(workflow).toContain('aws ecs wait services-stable');
expect(workflow).toContain('--import-existing-resources');
}
});
This “test-the-test” approach ensures the two CI systems never drift apart.