diff --git a/.github/workflows/deploy_staging.yml b/.github/workflows/deploy_staging.yml new file mode 100644 index 000000000..a524da5d8 --- /dev/null +++ b/.github/workflows/deploy_staging.yml @@ -0,0 +1,19 @@ +name: Deploy to Staging +on: + push: + branches: + - staging + +jobs: + docker-image: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: serlo/configure-repositories/actions/setup-node@main + - uses: google-github-actions/auth@v2 + with: + credentials_json: '${{ secrets.GCP_KEY_CONTAINER_REGISTRY }}' + - run: gcloud auth configure-docker + - uses: google-github-actions/setup-gcloud@v2 + - run: yarn deploy:images:staging + # TODO: delete pod diff --git a/package.json b/package.json index 2e7f1aa6d..f13844649 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "check:unused-exports": "ts-unused-exports tsconfig.json --excludePathsFromReport=packages/types/ --excludePathsFromReport=packages/server/src/types.ts --ignoreFiles=/dist/", "codegen": "lerna run --stream codegen", "deploy:images": "lerna run --stream deploy:image", + "deploy:images:staging": "lerna run --stream deploy:image:staging", "docker:build": "run-s \"docker:build:*\"", "docker:build:server": "docker build -f packages/server/docker/server/Dockerfile -t api-server-local-build:latest .", "docker:build:swr-queue-worker": "docker build -f packages/server/docker/swr-queue-worker/Dockerfile -t api-swr-queue-worker-local-build:latest .", diff --git a/packages/server/package.json b/packages/server/package.json index 244347858..66fb0d57f 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -14,7 +14,8 @@ "build:server": "yarn _build --format cjs --target node --entry src/server.ts", "build:swr-queue-worker": "yarn _build --format cjs --target node --entry src/swr-queue-worker.ts", "codegen": "graphql-codegen --config codegen.yml", - "deploy:image": "ts-node --experimental-specifier-resolution=node scripts/deploy" + "deploy:image": "ts-node --experimental-specifier-resolution=node scripts/deploy", + "deploy:image:staging": "ts-node --experimental-specifier-resolution=node scripts/deploy-staging" }, "dependencies": { "bee-queue": "^1.7.1" diff --git a/packages/server/scripts/deploy-staging.ts b/packages/server/scripts/deploy-staging.ts new file mode 100644 index 000000000..020c81145 --- /dev/null +++ b/packages/server/scripts/deploy-staging.ts @@ -0,0 +1,67 @@ +import { spawnSync } from 'node:child_process' +import * as path from 'node:path' +import { fileURLToPath } from 'node:url' + + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) + +const root = path.join(__dirname, '..') + +void run() + +function run() { + buildDockerImage({ + name: 'api-server', + Dockerfile: path.join(root, 'docker', 'server', 'Dockerfile'), + context: '../..', + envName: 'staging' + }) + buildDockerImage({ + name: 'api-swr-queue-worker', + Dockerfile: path.join(root, 'docker', 'swr-queue-worker', 'Dockerfile'), + context: '../..', + envName: 'staging' + }) +} + +function buildDockerImage({ + name, + Dockerfile, + context, + envName +}: DockerImageOptions) { + const remoteName = `eu.gcr.io/serlo-shared/${name}` + const date = new Date + const timestamp = `${date.toISOString().split('T')[0]}-${date.getTime()}` + + const {stdout: gitHash} = spawnSync( + 'git', + ['rev-parse', '--short', 'HEAD'], + ) + + const remoteTags = toTags(remoteName, [envName, timestamp, gitHash.toString()]) + const tags = [...remoteTags, ...toTags(name, [envName])] + + spawnSync( + 'docker', + ['build', '-f', Dockerfile, ...tags.flatMap((tag) => ['-t', tag]), context], + { stdio: 'inherit' }, + ) + + remoteTags.forEach((remoteTag) => { + // eslint-disable-next-line no-console + console.log('Pushing', remoteTag) + spawnSync('docker', ['push', remoteTag], { stdio: 'inherit' }) + }) +} + +function toTags(name: string, versions: string[]) { + return versions.map((version) => `${name}:${version}`) +} + +interface DockerImageOptions { + name: string + Dockerfile: string + context: string + envName: 'staging' | 'production' +}