@catladder/pipeline 1.115.0 → 1.117.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundles/catladder-gitlab/index.js +1 -1
- package/dist/constants.js +1 -1
- package/dist/deploy/cloudRun/artifactsRegistry.d.ts +19 -0
- package/dist/deploy/cloudRun/artifactsRegistry.js +117 -0
- package/dist/deploy/cloudRun/cleanup.d.ts +2 -0
- package/dist/deploy/cloudRun/cleanup.js +51 -0
- package/dist/deploy/cloudRun/cloudRunRevisions.d.ts +2 -0
- package/dist/deploy/cloudRun/cloudRunRevisions.js +61 -0
- package/dist/deploy/cloudRun/deployJob.js +13 -14
- package/dist/deploy/cloudRun/utils/getServiceName.d.ts +2 -0
- package/dist/deploy/cloudRun/utils/getServiceName.js +8 -0
- package/dist/deploy/cloudRun/utils/removeFirstLinesFromCommandOutput.d.ts +9 -0
- package/dist/deploy/cloudRun/utils/removeFirstLinesFromCommandOutput.js +16 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/examples/__snapshots__/cloud-run-memory-limit.ts.snap +46 -8
- package/examples/__snapshots__/cloud-run-no-cpu-throttling.ts.snap +46 -8
- package/examples/__snapshots__/cloud-run-non-public.ts.snap +46 -8
- package/examples/__snapshots__/cloud-run-with-sql-reuse-db.ts.snap +92 -16
- package/examples/__snapshots__/cloud-run-with-sql.ts.snap +92 -16
- package/examples/__snapshots__/custom-build-job-with-tests.ts.snap +46 -8
- package/examples/__snapshots__/custom-build-job.ts.snap +46 -8
- package/examples/__snapshots__/custom-sbom-java.ts.snap +46 -8
- package/examples/__snapshots__/native-app.ts.snap +46 -8
- package/examples/__snapshots__/node-build-with-custom-image.ts.snap +46 -8
- package/package.json +1 -1
- package/src/deploy/cloudRun/artifactsRegistry.ts +119 -0
- package/src/deploy/cloudRun/cleanup.ts +30 -0
- package/src/deploy/cloudRun/cloudRunRevisions.ts +67 -0
- package/src/deploy/cloudRun/deployJob.ts +46 -44
- package/src/deploy/cloudRun/utils/getServiceName.ts +3 -0
- package/src/deploy/cloudRun/utils/removeFirstLinesFromCommandOutput.ts +12 -0
|
@@ -245,21 +245,28 @@ COPY --chown=node:node .yarn /app/.yarn",
|
|
|
245
245
|
},
|
|
246
246
|
],
|
|
247
247
|
"script": [
|
|
248
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."",
|
|
248
249
|
"echo $CL_dev_www_GCLOUD_DEPLOY_credentialsKey > ./____keyfile.json
|
|
249
250
|
",
|
|
250
251
|
"gcloud auth activate-service-account --key-file="./____keyfile.json"",
|
|
251
252
|
"export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe asdf --format="value(projectNumber)")",
|
|
252
253
|
"echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"",
|
|
253
|
-
"echo -e "\\e[
|
|
254
|
+
"echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"",
|
|
255
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):pushToArtifactRegistry[collapsed=true]\\r\\e[0KPushing image to artifacts registry"",
|
|
254
256
|
"docker login --username gitlab-ci-token --password $CI_JOB_TOKEN $CI_REGISTRY",
|
|
255
257
|
"gcloud auth configure-docker asia-east1-docker.pkg.dev",
|
|
256
258
|
"docker pull $DOCKER_IMAGE:$DOCKER_IMAGE_TAG",
|
|
257
259
|
"docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/www:$DOCKER_IMAGE_TAG",
|
|
258
260
|
"docker push asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/www:$DOCKER_IMAGE_TAG",
|
|
259
261
|
"echo -e "\\e[0Ksection_end:$(date +%s):pushToArtifactRegistry\\r\\e[0K"",
|
|
262
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"",
|
|
260
263
|
"echo "$ENV_VARS" > ____envvars.yaml",
|
|
261
264
|
"gcloud run deploy pan-test-app-dev-www --command="yarn,start" --image=asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/www:$DOCKER_IMAGE_TAG --project=asdf --region=asia-east1 --labels=customer-name=pan,component-name=www,app-name=test-app,env-type=dev,env-name=dev,build-type=node --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --cpu-boost",
|
|
262
|
-
"
|
|
265
|
+
"echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"",
|
|
266
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"",
|
|
267
|
+
"gcloud run revisions list --project=asdf --region=asia-east1 --service=pan-test-app-dev-www --limit=unlimited --sort-by=metadata.creationTimestamp --format="value(name)" --filter='(status.conditions.status=False OR status.conditions.status=Unknown)' | while read -r revisionname; do gcloud run revisions delete --project=asdf --region=asia-east1 --quiet $revisionname ; done",
|
|
268
|
+
"gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/www --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/www@$version --quiet --delete-tags; done",
|
|
269
|
+
"echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"",
|
|
263
270
|
"echo Uploading SBOM to Dependency Track",
|
|
264
271
|
"/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/www" "https://pan-test-app-dev-www-unknown-host.example.com" "__sbom.json" vex.json || true",
|
|
265
272
|
],
|
|
@@ -347,6 +354,7 @@ _ALL_ENV_VAR_KEYS: '["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_ID","BUILD_INF
|
|
|
347
354
|
",
|
|
348
355
|
"gcloud auth activate-service-account --key-file="./____keyfile.json"",
|
|
349
356
|
"gcloud run services delete pan-test-app-dev-www --project=asdf --region=asia-east1",
|
|
357
|
+
"gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/www --quiet --delete-tags",
|
|
350
358
|
"echo Disabling component in Dependency Track",
|
|
351
359
|
"/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/www" "https://pan-test-app-dev-www-unknown-host.example.com" || true",
|
|
352
360
|
"set -e",
|
|
@@ -764,21 +772,31 @@ COPY --chown=node:node .yarn /app/.yarn",
|
|
|
764
772
|
},
|
|
765
773
|
],
|
|
766
774
|
"script": [
|
|
775
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."",
|
|
767
776
|
"echo $CL_review_www_GCLOUD_DEPLOY_credentialsKey > ./____keyfile.json
|
|
768
777
|
",
|
|
769
778
|
"gcloud auth activate-service-account --key-file="./____keyfile.json"",
|
|
770
779
|
"export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe asdf --format="value(projectNumber)")",
|
|
771
780
|
"echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"",
|
|
772
|
-
"echo -e "\\e[
|
|
781
|
+
"echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"",
|
|
782
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):pushToArtifactRegistry[collapsed=true]\\r\\e[0KPushing image to artifacts registry"",
|
|
773
783
|
"docker login --username gitlab-ci-token --password $CI_JOB_TOKEN $CI_REGISTRY",
|
|
774
784
|
"gcloud auth configure-docker asia-east1-docker.pkg.dev",
|
|
775
785
|
"docker pull $DOCKER_IMAGE:$DOCKER_IMAGE_TAG",
|
|
776
786
|
"docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/www/mr1234:$DOCKER_IMAGE_TAG",
|
|
777
787
|
"docker push asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/www/mr1234:$DOCKER_IMAGE_TAG",
|
|
778
788
|
"echo -e "\\e[0Ksection_end:$(date +%s):pushToArtifactRegistry\\r\\e[0K"",
|
|
789
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"",
|
|
779
790
|
"echo "$ENV_VARS" > ____envvars.yaml",
|
|
780
791
|
"gcloud run deploy pan-test-app-review-mr1234-www --command="yarn,start" --image=asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/www/mr1234:$DOCKER_IMAGE_TAG --project=asdf --region=asia-east1 --labels=customer-name=pan,component-name=www,app-name=test-app,env-type=review,env-name=review,build-type=node --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --cpu-boost",
|
|
781
|
-
"
|
|
792
|
+
"echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"",
|
|
793
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"",
|
|
794
|
+
"gcloud run revisions list --project=asdf --region=asia-east1 --service=pan-test-app-review-mr1234-www --limit=unlimited --sort-by=metadata.creationTimestamp --format="value(name)" --filter='(status.conditions.status=False OR status.conditions.status=Unknown)' | while read -r revisionname; do gcloud run revisions delete --project=asdf --region=asia-east1 --quiet $revisionname ; done",
|
|
795
|
+
"gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/www/mr1234 --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/www/mr1234@$version --quiet --delete-tags; done",
|
|
796
|
+
"set +e",
|
|
797
|
+
"gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/www --quiet --delete-tags",
|
|
798
|
+
"set -e",
|
|
799
|
+
"echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"",
|
|
782
800
|
"echo Uploading SBOM to Dependency Track",
|
|
783
801
|
"/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/www" "https://pan-test-app-review-mr1234-www-unknown-host.example.com" "__sbom.json" vex.json || true",
|
|
784
802
|
],
|
|
@@ -866,6 +884,10 @@ _ALL_ENV_VAR_KEYS: '["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_ID","BUILD_INF
|
|
|
866
884
|
",
|
|
867
885
|
"gcloud auth activate-service-account --key-file="./____keyfile.json"",
|
|
868
886
|
"gcloud run services delete pan-test-app-review-mr1234-www --project=asdf --region=asia-east1",
|
|
887
|
+
"gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/www/mr1234 --quiet --delete-tags",
|
|
888
|
+
"set +e",
|
|
889
|
+
"gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/www --quiet --delete-tags",
|
|
890
|
+
"set -e",
|
|
869
891
|
"echo Disabling component in Dependency Track",
|
|
870
892
|
"/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/www" "https://pan-test-app-review-mr1234-www-unknown-host.example.com" || true",
|
|
871
893
|
"set -e",
|
|
@@ -1371,21 +1393,28 @@ COPY --chown=node:node .yarn /app/.yarn",
|
|
|
1371
1393
|
},
|
|
1372
1394
|
],
|
|
1373
1395
|
"script": [
|
|
1396
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."",
|
|
1374
1397
|
"echo $CL_prod_www_GCLOUD_DEPLOY_credentialsKey > ./____keyfile.json
|
|
1375
1398
|
",
|
|
1376
1399
|
"gcloud auth activate-service-account --key-file="./____keyfile.json"",
|
|
1377
1400
|
"export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe asdf --format="value(projectNumber)")",
|
|
1378
1401
|
"echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"",
|
|
1379
|
-
"echo -e "\\e[
|
|
1402
|
+
"echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"",
|
|
1403
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):pushToArtifactRegistry[collapsed=true]\\r\\e[0KPushing image to artifacts registry"",
|
|
1380
1404
|
"docker login --username gitlab-ci-token --password $CI_JOB_TOKEN $CI_REGISTRY",
|
|
1381
1405
|
"gcloud auth configure-docker asia-east1-docker.pkg.dev",
|
|
1382
1406
|
"docker pull $DOCKER_IMAGE:$DOCKER_IMAGE_TAG",
|
|
1383
1407
|
"docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/www:$DOCKER_IMAGE_TAG",
|
|
1384
1408
|
"docker push asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/www:$DOCKER_IMAGE_TAG",
|
|
1385
1409
|
"echo -e "\\e[0Ksection_end:$(date +%s):pushToArtifactRegistry\\r\\e[0K"",
|
|
1410
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"",
|
|
1386
1411
|
"echo "$ENV_VARS" > ____envvars.yaml",
|
|
1387
1412
|
"gcloud run deploy pan-test-app-prod-www --command="yarn,start" --image=asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/www:$DOCKER_IMAGE_TAG --project=asdf --region=asia-east1 --labels=customer-name=pan,component-name=www,app-name=test-app,env-type=prod,env-name=prod,build-type=node --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --cpu-boost",
|
|
1388
|
-
"
|
|
1413
|
+
"echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"",
|
|
1414
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"",
|
|
1415
|
+
"gcloud run revisions list --project=asdf --region=asia-east1 --service=pan-test-app-prod-www --limit=unlimited --sort-by=metadata.creationTimestamp --format="value(name)" --filter='(status.conditions.status=False OR status.conditions.status=Unknown)' | tail -n +6 | while read -r revisionname; do gcloud run revisions delete --project=asdf --region=asia-east1 --quiet $revisionname ; done",
|
|
1416
|
+
"gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/www --sort-by=~CREATE_TIME --format="value(version)" | tail -n +7 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/www@$version --quiet --delete-tags; done",
|
|
1417
|
+
"echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"",
|
|
1389
1418
|
"echo Uploading SBOM to Dependency Track",
|
|
1390
1419
|
"/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/www" "https://pan-test-app-prod-www-unknown-host.example.com" "__sbom.json" vex.json || true",
|
|
1391
1420
|
],
|
|
@@ -1482,21 +1511,28 @@ _ALL_ENV_VAR_KEYS: '["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_ID","BUILD_INF
|
|
|
1482
1511
|
},
|
|
1483
1512
|
],
|
|
1484
1513
|
"script": [
|
|
1514
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."",
|
|
1485
1515
|
"echo $CL_stage_www_GCLOUD_DEPLOY_credentialsKey > ./____keyfile.json
|
|
1486
1516
|
",
|
|
1487
1517
|
"gcloud auth activate-service-account --key-file="./____keyfile.json"",
|
|
1488
1518
|
"export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe asdf --format="value(projectNumber)")",
|
|
1489
1519
|
"echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"",
|
|
1490
|
-
"echo -e "\\e[
|
|
1520
|
+
"echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"",
|
|
1521
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):pushToArtifactRegistry[collapsed=true]\\r\\e[0KPushing image to artifacts registry"",
|
|
1491
1522
|
"docker login --username gitlab-ci-token --password $CI_JOB_TOKEN $CI_REGISTRY",
|
|
1492
1523
|
"gcloud auth configure-docker asia-east1-docker.pkg.dev",
|
|
1493
1524
|
"docker pull $DOCKER_IMAGE:$DOCKER_IMAGE_TAG",
|
|
1494
1525
|
"docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/www:$DOCKER_IMAGE_TAG",
|
|
1495
1526
|
"docker push asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/www:$DOCKER_IMAGE_TAG",
|
|
1496
1527
|
"echo -e "\\e[0Ksection_end:$(date +%s):pushToArtifactRegistry\\r\\e[0K"",
|
|
1528
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"",
|
|
1497
1529
|
"echo "$ENV_VARS" > ____envvars.yaml",
|
|
1498
1530
|
"gcloud run deploy pan-test-app-stage-www --command="yarn,start" --image=asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/www:$DOCKER_IMAGE_TAG --project=asdf --region=asia-east1 --labels=customer-name=pan,component-name=www,app-name=test-app,env-type=stage,env-name=stage,build-type=node --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --cpu-boost",
|
|
1499
|
-
"
|
|
1531
|
+
"echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"",
|
|
1532
|
+
"echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"",
|
|
1533
|
+
"gcloud run revisions list --project=asdf --region=asia-east1 --service=pan-test-app-stage-www --limit=unlimited --sort-by=metadata.creationTimestamp --format="value(name)" --filter='(status.conditions.status=False OR status.conditions.status=Unknown)' | while read -r revisionname; do gcloud run revisions delete --project=asdf --region=asia-east1 --quiet $revisionname ; done",
|
|
1534
|
+
"gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/www --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/www@$version --quiet --delete-tags; done",
|
|
1535
|
+
"echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"",
|
|
1500
1536
|
"echo Uploading SBOM to Dependency Track",
|
|
1501
1537
|
"/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/www" "https://pan-test-app-stage-www-unknown-host.example.com" "__sbom.json" vex.json || true",
|
|
1502
1538
|
],
|
|
@@ -1584,6 +1620,7 @@ _ALL_ENV_VAR_KEYS: '["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_ID","BUILD_INF
|
|
|
1584
1620
|
",
|
|
1585
1621
|
"gcloud auth activate-service-account --key-file="./____keyfile.json"",
|
|
1586
1622
|
"gcloud run services delete pan-test-app-prod-www --project=asdf --region=asia-east1",
|
|
1623
|
+
"gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/www --quiet --delete-tags",
|
|
1587
1624
|
"echo Disabling component in Dependency Track",
|
|
1588
1625
|
"/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/www" "https://pan-test-app-prod-www-unknown-host.example.com" || true",
|
|
1589
1626
|
"set -e",
|
|
@@ -1631,6 +1668,7 @@ _ALL_ENV_VAR_KEYS: '["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_ID","BUILD_INF
|
|
|
1631
1668
|
",
|
|
1632
1669
|
"gcloud auth activate-service-account --key-file="./____keyfile.json"",
|
|
1633
1670
|
"gcloud run services delete pan-test-app-stage-www --project=asdf --region=asia-east1",
|
|
1671
|
+
"gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/www --quiet --delete-tags",
|
|
1634
1672
|
"echo Disabling component in Dependency Track",
|
|
1635
1673
|
"/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/www" "https://pan-test-app-stage-www-unknown-host.example.com" || true",
|
|
1636
1674
|
"set -e",
|
package/package.json
CHANGED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { gitlabDockerLogin } from "../../build/docker";
|
|
2
|
+
import type { Context } from "../../types/context";
|
|
3
|
+
import { allowFailureInScripts } from "../../utils/gitlab";
|
|
4
|
+
import { isOfDeployType } from "../types";
|
|
5
|
+
import { removeFirstLinesFromCommandOutput } from "./utils/removeFirstLinesFromCommandOutput";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* lecacyReviewImageName is only temporary. In old versions the images had no reviewslug in review apps, which makes cleanup harder. We delete all those images now, but need the path
|
|
10
|
+
*/
|
|
11
|
+
export const getArtifactsRegistryImageName = (
|
|
12
|
+
context: Context,
|
|
13
|
+
lecacyReviewImageName = false
|
|
14
|
+
) => {
|
|
15
|
+
const deployConfig = context.componentConfig.deploy;
|
|
16
|
+
|
|
17
|
+
if (!isOfDeployType(deployConfig, "google-cloudrun")) {
|
|
18
|
+
// should not happen
|
|
19
|
+
throw new Error("deploy config is wrong");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (lecacyReviewImageName && context.environment.envType !== "review") {
|
|
23
|
+
throw new Error("lecacyReviewImageName is only allowed for review app");
|
|
24
|
+
}
|
|
25
|
+
const fullAppName = `${context.fullConfig.customerName}-${context.fullConfig.appName}`;
|
|
26
|
+
|
|
27
|
+
const dockerUrl = `${deployConfig.region}-docker.pkg.dev/${deployConfig.projectId}/catladder-deploy/${fullAppName}`;
|
|
28
|
+
const gcloudImagePath = [
|
|
29
|
+
dockerUrl,
|
|
30
|
+
context.environment.shortName,
|
|
31
|
+
context.componentName,
|
|
32
|
+
|
|
33
|
+
...(context.environment.envType === "review" && !lecacyReviewImageName
|
|
34
|
+
? [context.commitInfo?.reviewSlug]
|
|
35
|
+
: []),
|
|
36
|
+
];
|
|
37
|
+
return gcloudImagePath.join("/");
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const getArtifactsRegistryImage = (context: Context) =>
|
|
41
|
+
`${getArtifactsRegistryImageName(context)}:$DOCKER_IMAGE_TAG`;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* commands to pull the image from the default registry and pushes it to google artifact registry. We might build and push directly to google artifact registry in the future
|
|
45
|
+
*/
|
|
46
|
+
export const getPushToArtifactsRegistryCommands = (context: Context) => {
|
|
47
|
+
const deployConfig = context.componentConfig.deploy;
|
|
48
|
+
|
|
49
|
+
if (!isOfDeployType(deployConfig, "google-cloudrun")) {
|
|
50
|
+
// should not happen
|
|
51
|
+
throw new Error("deploy config is wrong");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const fullImageName = getArtifactsRegistryImageName(context);
|
|
55
|
+
|
|
56
|
+
return [
|
|
57
|
+
gitlabDockerLogin,
|
|
58
|
+
`gcloud auth configure-docker ${deployConfig.region}-docker.pkg.dev`,
|
|
59
|
+
`docker pull $DOCKER_IMAGE:$DOCKER_IMAGE_TAG`,
|
|
60
|
+
`docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG ${fullImageName}:$DOCKER_IMAGE_TAG`,
|
|
61
|
+
`docker push ${fullImageName}:$DOCKER_IMAGE_TAG`,
|
|
62
|
+
];
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const getDeleteImageCommands = (fullImageName: string, keepNewest = 0) => {
|
|
66
|
+
if (keepNewest === 0) {
|
|
67
|
+
// no need to list tags, we delete the whole thing
|
|
68
|
+
return [
|
|
69
|
+
`gcloud artifacts docker images delete ${fullImageName} --quiet --delete-tags`,
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
// delete unused tags
|
|
73
|
+
const listAllImagesCommand = `gcloud artifacts docker images list ${fullImageName} --sort-by=~CREATE_TIME --format="value(version)"`;
|
|
74
|
+
|
|
75
|
+
const listImagesToDeletecommand = removeFirstLinesFromCommandOutput(
|
|
76
|
+
listAllImagesCommand,
|
|
77
|
+
keepNewest
|
|
78
|
+
);
|
|
79
|
+
const deleteImageCommand = `gcloud artifacts docker images delete ${fullImageName}@$version --quiet --delete-tags`;
|
|
80
|
+
|
|
81
|
+
const deleteImagesCommand = `${listImagesToDeletecommand} | while read -r version; do ${deleteImageCommand}; done`;
|
|
82
|
+
|
|
83
|
+
return [deleteImagesCommand];
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* commands to delete unused images.
|
|
88
|
+
*
|
|
89
|
+
* @param context
|
|
90
|
+
* @param keep how many of the newest images to keep
|
|
91
|
+
* @returns
|
|
92
|
+
*/
|
|
93
|
+
export const getDeleteUnusedImagesCommands = (context: Context, keep = 0) => {
|
|
94
|
+
const deployConfig = context.componentConfig.deploy;
|
|
95
|
+
if (deployConfig === false) {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
if (!isOfDeployType(deployConfig, "google-cloudrun")) {
|
|
99
|
+
// should not happen
|
|
100
|
+
throw new Error("deploy config is wrong");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const fullImageName = getArtifactsRegistryImageName(context);
|
|
104
|
+
|
|
105
|
+
return [
|
|
106
|
+
...getDeleteImageCommands(fullImageName, keep),
|
|
107
|
+
// because a recent version of catladder had no review-slug in the image name, we have to delete those as well
|
|
108
|
+
// we can later remove this line in some months
|
|
109
|
+
|
|
110
|
+
...(context.environment.envType === "review"
|
|
111
|
+
? allowFailureInScripts(
|
|
112
|
+
getDeleteImageCommands(
|
|
113
|
+
getArtifactsRegistryImageName(context, true),
|
|
114
|
+
0
|
|
115
|
+
)
|
|
116
|
+
)
|
|
117
|
+
: []),
|
|
118
|
+
];
|
|
119
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Context } from "../../types/context";
|
|
2
|
+
import { getDeleteUnusedImagesCommands } from "./artifactsRegistry";
|
|
3
|
+
import { getDeleteUnusedRevisionsCommands } from "./cloudRunRevisions";
|
|
4
|
+
|
|
5
|
+
export const getRemoveOldRevisionsAndImagesCommand = (
|
|
6
|
+
context: Context,
|
|
7
|
+
when: "postDeploy" | "onStop"
|
|
8
|
+
) => {
|
|
9
|
+
if (when === "onStop") {
|
|
10
|
+
// service is already deleted, so we don't need to delete old revisions, just delete all images
|
|
11
|
+
return getDeleteUnusedImagesCommands(context);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// this number only targets inactive revisions
|
|
15
|
+
const revisionsToKeep = context.environment.envType === "prod" ? 5 : 0;
|
|
16
|
+
|
|
17
|
+
// this number needs to be higher than inactive after deploy, so we add one
|
|
18
|
+
const imagesToKeep = revisionsToKeep + 1;
|
|
19
|
+
|
|
20
|
+
const deleteOldRevisionsCommands = getDeleteUnusedRevisionsCommands(
|
|
21
|
+
context,
|
|
22
|
+
revisionsToKeep
|
|
23
|
+
);
|
|
24
|
+
const deleteOldImagesCommands = getDeleteUnusedImagesCommands(
|
|
25
|
+
context,
|
|
26
|
+
imagesToKeep
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
return [...deleteOldRevisionsCommands, ...deleteOldImagesCommands];
|
|
30
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Context } from "../../types/context";
|
|
2
|
+
import { isOfDeployType } from "../types";
|
|
3
|
+
import { createArgsString } from "./utils/createArgsString";
|
|
4
|
+
import { getServiceName } from "./utils/getServiceName";
|
|
5
|
+
import { removeFirstLinesFromCommandOutput } from "./utils/removeFirstLinesFromCommandOutput";
|
|
6
|
+
|
|
7
|
+
const getListRevisionsCommand = (
|
|
8
|
+
context: Context,
|
|
9
|
+
args: {
|
|
10
|
+
filter?: string;
|
|
11
|
+
format: string;
|
|
12
|
+
}
|
|
13
|
+
) => {
|
|
14
|
+
const serviceName = getServiceName(context);
|
|
15
|
+
const deployConfig = context.componentConfig.deploy;
|
|
16
|
+
|
|
17
|
+
if (!deployConfig || !isOfDeployType(deployConfig, "google-cloudrun")) {
|
|
18
|
+
// should not happen
|
|
19
|
+
throw new Error("deploy config is wrong");
|
|
20
|
+
}
|
|
21
|
+
const filterRevisionArgs = {
|
|
22
|
+
project: deployConfig.projectId,
|
|
23
|
+
region: deployConfig.region,
|
|
24
|
+
// only show inactive revisions
|
|
25
|
+
service: serviceName,
|
|
26
|
+
|
|
27
|
+
limit: "unlimited", // is actualy the default
|
|
28
|
+
"sort-by": "metadata.creationTimestamp",
|
|
29
|
+
...args,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// this prints out all inactive images of the given app
|
|
33
|
+
return `gcloud run revisions list ${createArgsString(filterRevisionArgs)}`;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const getDeleteUnusedRevisionsCommands = (
|
|
37
|
+
context: Context,
|
|
38
|
+
keep: number
|
|
39
|
+
) => {
|
|
40
|
+
const deployConfig = context.componentConfig.deploy;
|
|
41
|
+
if (deployConfig === false) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
if (!isOfDeployType(deployConfig, "google-cloudrun")) {
|
|
45
|
+
// should not happen
|
|
46
|
+
throw new Error("deploy config is wrong");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// this prints out all inactive images of the given app
|
|
50
|
+
const listAllInactiveRevisionsCmd = getListRevisionsCommand(context, {
|
|
51
|
+
format: `"value(name)"`,
|
|
52
|
+
filter: `'(status.conditions.status=False OR status.conditions.status=Unknown)'`,
|
|
53
|
+
});
|
|
54
|
+
// this removes the newest `revisionsToKeep` images
|
|
55
|
+
const listRevisionsToDeleteCmd = removeFirstLinesFromCommandOutput(
|
|
56
|
+
listAllInactiveRevisionsCmd,
|
|
57
|
+
keep
|
|
58
|
+
);
|
|
59
|
+
const deleteRevisionCmd = `gcloud run revisions delete ${createArgsString({
|
|
60
|
+
project: deployConfig.projectId,
|
|
61
|
+
region: deployConfig.region,
|
|
62
|
+
quiet: true,
|
|
63
|
+
})} $revisionname `;
|
|
64
|
+
|
|
65
|
+
const deleteRevisionsCmd = `${listRevisionsToDeleteCmd} | while read -r revisionname; do ${deleteRevisionCmd}; done`;
|
|
66
|
+
return [deleteRevisionsCmd];
|
|
67
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { dump } from "js-yaml";
|
|
2
2
|
import { merge, omit } from "lodash";
|
|
3
3
|
import { GCLOUD_DEPLOY_CREDENTIALS_KEY } from ".";
|
|
4
|
-
import { getDockerJobBaseProps
|
|
4
|
+
import { getDockerJobBaseProps } from "../../build/docker";
|
|
5
5
|
import { getLabels } from "../../context/getLabels";
|
|
6
6
|
import { getRunnerImage } from "../../runner";
|
|
7
7
|
import type { Context } from "../../types/context";
|
|
@@ -26,6 +26,12 @@ import {
|
|
|
26
26
|
} from "./utils/database";
|
|
27
27
|
import { gcloudServiceAccountLoginCommands } from "./utils/gcloudServiceAccountLoginCommands";
|
|
28
28
|
import { getCloudRunJobName } from "./utils/jobName";
|
|
29
|
+
import {
|
|
30
|
+
getArtifactsRegistryImage,
|
|
31
|
+
getPushToArtifactsRegistryCommands,
|
|
32
|
+
} from "./artifactsRegistry";
|
|
33
|
+
import { getServiceName } from "./utils/getServiceName";
|
|
34
|
+
import { getRemoveOldRevisionsAndImagesCommand } from "./cleanup";
|
|
29
35
|
|
|
30
36
|
const setExtraVarsScripts = (deployConfig: DeployConfigCloudRun) => [
|
|
31
37
|
`export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe ${deployConfig.projectId} --format="value(projectNumber)")`,
|
|
@@ -44,29 +50,6 @@ export const createGoogleCloudRunDeployJobs = (
|
|
|
44
50
|
throw new Error("deploy config is wrong");
|
|
45
51
|
}
|
|
46
52
|
|
|
47
|
-
const fullAppName = `${context.fullConfig.customerName}-${context.fullConfig.appName}`;
|
|
48
|
-
const dockerUrl = `${deployConfig.region}-docker.pkg.dev/${deployConfig.projectId}/catladder-deploy/${fullAppName}`;
|
|
49
|
-
const gcloudImagePath = [
|
|
50
|
-
dockerUrl,
|
|
51
|
-
context.environment.shortName,
|
|
52
|
-
context.componentName,
|
|
53
|
-
|
|
54
|
-
...(context.environment.envType === "review"
|
|
55
|
-
? [context.commitInfo?.reviewSlug]
|
|
56
|
-
: []),
|
|
57
|
-
];
|
|
58
|
-
const gcloudImageName = `${gcloudImagePath.join("/")}:$DOCKER_IMAGE_TAG`;
|
|
59
|
-
|
|
60
|
-
const pushImageToArtifactsRegistry = collapseableSection(
|
|
61
|
-
"pushToArtifactRegistry",
|
|
62
|
-
"pushing image to artifacts registry"
|
|
63
|
-
)([
|
|
64
|
-
gitlabDockerLogin,
|
|
65
|
-
`gcloud auth configure-docker ${deployConfig.region}-docker.pkg.dev`,
|
|
66
|
-
`docker pull $DOCKER_IMAGE:$DOCKER_IMAGE_TAG`,
|
|
67
|
-
`docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG ${gcloudImageName}`,
|
|
68
|
-
`docker push ${gcloudImageName}`,
|
|
69
|
-
]);
|
|
70
53
|
const allEnvVars = omit(
|
|
71
54
|
context.environment.envVars,
|
|
72
55
|
GCLOUD_DEPLOY_CREDENTIALS_KEY
|
|
@@ -82,7 +65,7 @@ export const createGoogleCloudRunDeployJobs = (
|
|
|
82
65
|
};
|
|
83
66
|
|
|
84
67
|
const commonDeployArgs = {
|
|
85
|
-
image:
|
|
68
|
+
image: getArtifactsRegistryImage(context),
|
|
86
69
|
...commonArgs,
|
|
87
70
|
"set-cloudsql-instances": deployConfig.cloudSql
|
|
88
71
|
? deployConfig.cloudSql.instanceConnectionName
|
|
@@ -90,7 +73,7 @@ export const createGoogleCloudRunDeployJobs = (
|
|
|
90
73
|
labels: labelsString,
|
|
91
74
|
};
|
|
92
75
|
|
|
93
|
-
const serviceName = context
|
|
76
|
+
const serviceName = getServiceName(context);
|
|
94
77
|
|
|
95
78
|
const getFullJobName = (name: string) =>
|
|
96
79
|
getCloudRunJobName(context.environment.fullName, name);
|
|
@@ -228,26 +211,43 @@ export const createGoogleCloudRunDeployJobs = (
|
|
|
228
211
|
]);
|
|
229
212
|
|
|
230
213
|
const deployScripts = [
|
|
231
|
-
...
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
...
|
|
239
|
-
|
|
240
|
-
|
|
214
|
+
...collapseableSection(
|
|
215
|
+
"prepare",
|
|
216
|
+
"Prepare..."
|
|
217
|
+
)([
|
|
218
|
+
...gcloudServiceAccountLoginCommands(context),
|
|
219
|
+
...setExtraVarsScripts(deployConfig),
|
|
220
|
+
]),
|
|
221
|
+
...collapseableSection(
|
|
222
|
+
"pushToArtifactRegistry",
|
|
223
|
+
"Pushing image to artifacts registry"
|
|
224
|
+
)(getPushToArtifactsRegistryCommands(context)),
|
|
225
|
+
...collapseableSection(
|
|
226
|
+
"deploy",
|
|
227
|
+
"Deploy to cloud run"
|
|
228
|
+
)([
|
|
229
|
+
`echo "$ENV_VARS" > ____envvars.yaml`, // TODO: split secrets out
|
|
230
|
+
...(deployConfig.cloudSql
|
|
231
|
+
? getDatabaseCreateScript(context, deployConfig) // we create the db, so that we can also delete it afterwards
|
|
232
|
+
: []),
|
|
233
|
+
...getCreateScheduleScripts(),
|
|
234
|
+
...getJobCreateScripts(),
|
|
235
|
+
...getJobRunScripts("preDeploy"),
|
|
241
236
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
237
|
+
...(deployConfig.service !== false
|
|
238
|
+
? [getServiceDeployScript(deployConfig.service)]
|
|
239
|
+
: []),
|
|
240
|
+
...Object.entries(deployConfig.additionalServices ?? {}).map(
|
|
241
|
+
([name, service]) => getServiceDeployScript(service, "-" + name)
|
|
242
|
+
),
|
|
243
|
+
...getJobRunScripts("postDeploy"),
|
|
244
|
+
]),
|
|
245
|
+
...collapseableSection(
|
|
246
|
+
"cleanup",
|
|
247
|
+
"Cleanup"
|
|
248
|
+
)(
|
|
249
|
+
getRemoveOldRevisionsAndImagesCommand(context, "postDeploy") // we cleanup inactive images both on deploy and stop
|
|
247
250
|
),
|
|
248
|
-
...getJobRunScripts("postDeploy"),
|
|
249
|
-
|
|
250
|
-
`docker image rm ${gcloudImageName}`,
|
|
251
251
|
...getDependencyTrackUploadScript(context),
|
|
252
252
|
];
|
|
253
253
|
|
|
@@ -265,6 +265,8 @@ export const createGoogleCloudRunDeployJobs = (
|
|
|
265
265
|
...(deployConfig.cloudSql && deployConfig.cloudSql.deleteDatabaseOnStop
|
|
266
266
|
? getDatabaseDeleteScript(context, deployConfig)
|
|
267
267
|
: []),
|
|
268
|
+
|
|
269
|
+
...getRemoveOldRevisionsAndImagesCommand(context, "onStop"), // we cleanup inactive images both on deploy and stop
|
|
268
270
|
...getDependencyTrackDeleteScript(context),
|
|
269
271
|
];
|
|
270
272
|
return createDeployementJobs(context, {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* takes a command and removes the first keep lines from the output
|
|
4
|
+
*
|
|
5
|
+
* @param cmd the command, its stdout is then limited
|
|
6
|
+
* @param removeFirstN how many lines to remove at the start of the command
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export const removeFirstLinesFromCommandOutput = (
|
|
10
|
+
cmd: string,
|
|
11
|
+
removeFirstN: number
|
|
12
|
+
) => (removeFirstN === 0 ? cmd : `${cmd} | tail -n +${removeFirstN + 1}`);
|