From f518770bc58ada25c1ee990fcdbf38418d9f0387 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 26 Jun 2026 15:02:27 +0000 Subject: [PATCH] Only virko can trigger deployments (PF-3369) Bump vendored lib-jsonnet to 358da535b48d02d139dee0974843d2e646b972fe and regenerate workflows. The deploymentTargets() helper now gates deploy jobs so they only run for deployment events created by gynzy-virko. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_0194WzrNYXRJKhejZT9gdpdF --- .github/jsonnet/GIT_VERSION | 2 +- .github/jsonnet/base.jsonnet | 6 +- .github/jsonnet/cache.jsonnet | 91 ++++- .github/jsonnet/complete-workflows.jsonnet | 36 +- .github/jsonnet/deployment.jsonnet | 5 +- .github/jsonnet/helm.jsonnet | 9 +- .github/jsonnet/images.jsonnet | 1 + .github/jsonnet/misc.jsonnet | 79 +++- .github/jsonnet/newrelic.jsonnet | 7 +- .github/jsonnet/pnpm.jsonnet | 197 ++++++++- .github/jsonnet/pulumi.jsonnet | 64 ++- .github/jsonnet/ruby.jsonnet | 7 +- .github/jsonnet/yarn.jsonnet | 48 ++- .github/workflows/Build Agent Images.yml | 240 ++++++++++- .github/workflows/CI.yml | 450 +++++++++++++++++++-- .github/workflows/Release.yml | 32 +- 16 files changed, 1154 insertions(+), 120 deletions(-) diff --git a/.github/jsonnet/GIT_VERSION b/.github/jsonnet/GIT_VERSION index 91009a41..7e1ee271 100644 --- a/.github/jsonnet/GIT_VERSION +++ b/.github/jsonnet/GIT_VERSION @@ -1 +1 @@ -85284ade969df3f45c01eb0a9c513267c0a60b81 +358da535b48d02d139dee0974843d2e646b972fe diff --git a/.github/jsonnet/base.jsonnet b/.github/jsonnet/base.jsonnet index 3aa91c35..cda50ddf 100644 --- a/.github/jsonnet/base.jsonnet +++ b/.github/jsonnet/base.jsonnet @@ -168,9 +168,10 @@ local misc = import 'misc.jsonnet'; * @param {string} [id=null] - Unique identifier for this step (used to reference outputs) * @param {string} [ifClause=null] - Conditional expression to determine if step should run * @param {boolean} [continueOnError=null] - Whether to continue job if this step fails + * @param {number} [timeoutMinutes=null] - Maximum minutes to run this step before failing * @returns {steps} - Array containing a single step object */ - action(name, uses, env=null, with=null, id=null, ifClause=null, continueOnError=null):: + action(name, uses, env=null, with=null, id=null, ifClause=null, continueOnError=null, timeoutMinutes=null):: [ { name: name, @@ -179,6 +180,7 @@ local misc = import 'misc.jsonnet'; + (if with != null && with != {} then { with: with } else {}) + (if id != null then { id: id } else {}) + (if ifClause != null then { 'if': ifClause } else {}) - + (if continueOnError == null then {} else { 'continue-on-error': continueOnError }), + + (if continueOnError == null then {} else { 'continue-on-error': continueOnError }) + + (if timeoutMinutes == null then {} else { 'timeout-minutes': timeoutMinutes }) ], } diff --git a/.github/jsonnet/cache.jsonnet b/.github/jsonnet/cache.jsonnet index 9bd425f5..20860b34 100644 --- a/.github/jsonnet/cache.jsonnet +++ b/.github/jsonnet/cache.jsonnet @@ -1,12 +1,14 @@ local base = import 'base.jsonnet'; +local images = import 'images.jsonnet'; +local misc = import 'misc.jsonnet'; { /** * Fetch a cache from the cache server. - * + * * This is a generic function that can be used to fetch any cache. It is advised to wrap this function * in a more specific function that fetches a specific cache, setting the cacheName and folders parameters. - * + * * To be paired with the uploadCache function. * * @param {string} cacheName - The name of the cache to fetch. The name of the repository is usually a good option. @@ -82,10 +84,10 @@ local base = import 'base.jsonnet'; /** * Uploads a cache to the cache server. - * + * * This is a generic function that can be used to upload any cache. It is advised to wrap this function * in a more specific function that uploads a specific cache, setting the cacheName and folders parameters. - * + * * To be paired with the fetchCache function. * * @param {string} cacheName - The name of the cache to upload. The name of the repository is usually a good option. @@ -141,4 +143,85 @@ local base = import 'base.jsonnet'; 'echo "Cache removed"\n', ifClause=ifClause, ), + +/** + * Daily (weekday) backup of the full repository (working tree + .git) to GCS as a zstd tar archive, + * then refreshes a 7-day signed HTTPS URL into the GIT_HTTPS_ARCHIVE_MIRROR repo secret. + * + * @param {string} [cron='0 1 * * 1-5'] - Schedule (UTC). Default 01:00 on weekdays. + * @param {string} [bucketPath='gs://gynzy-internal-files/git-mirror'] - Destination prefix. + * @returns {workflows} - GitHub Actions pipeline that mirrors the repository to GCS. + */ + updateGitCacheCron( + cron='0 1 * * 1-5', + ):: + local secret = self.secret; + local destUrl = 'gs://gynzy-internal-files/git-mirror/${GITHUB_REPOSITORY}.tar.zst'; + base.pipeline( + 'git-mirror-backup', + [ + base.ghJob( + 'git-mirror-backup', + image=images.cloud_sdk_image, + useCredentials=true, + timeoutMinutes=60, + steps=[ + // blobless=false: a backup must contain ALL git objects, not lazily-fetched blobs. + misc.checkout(fullClone=true, blobless=false, cloneTimeout=30, skipSeed=true), + base.step( + 'authenticate gcloud', + ||| + set -euo pipefail + # Write the key OUTSIDE the workspace so it never lands in the archive. + printf '%s' "$SERVICE_JSON" > "$RUNNER_TEMP/gce.json" + gcloud auth activate-service-account --key-file="$RUNNER_TEMP/gce.json" + |||, + shell='bash', + env={ SERVICE_JSON: misc.secret('SERVICE_JSON') }, + ), + base.step( + 'create and upload archive', + ||| + set -euo pipefail + # checkStat=minimal makes git compare only mtime+size (which tar preserves), + # not ctime/inode. Consumers that seed from this archive then see a clean tree + # and only write the real diff during checkout instead of rewriting every file. + git -C "$GITHUB_WORKSPACE" config --local core.checkStat minimal + + DEST="%s" + + # Upload to a temp object first, then atomically move into place so a partial + # upload can never sit at the final destination. + tar -C "$GITHUB_WORKSPACE" -c . | zstdmt -10 | gcloud storage cp - "${DEST}.tmp" + gcloud storage mv "${DEST}.tmp" "$DEST" + ||| % destUrl, + shell='bash', + ), + base.step( + 'refresh signed-url secret', + ||| + set -euo pipefail + DEST="%s" + URL="$(gcloud storage sign-url "$DEST" \ + --private-key-file="$RUNNER_TEMP/gce.json" --http-verb=GET --duration=7d \ + --format='value(signed_url)')" + echo "::add-mask::$URL" + gh secret set "GIT_HTTPS_ARCHIVE_MIRROR" --repo "$GITHUB_REPOSITORY" --body "$URL" + ||| % destUrl, + shell='bash', + env={ + GH_TOKEN: misc.secret('VIRKO_GITHUB_TOKEN'), + }, + ), + base.step( + 'remove credentials', + 'rm -f "$RUNNER_TEMP/gce.json"', + ifClause='${{ always() }}', + ), + ], + ), + ], + event={ schedule: [{ cron: cron }], workflow_dispatch: {} }, + permissions={ contents: 'read' }, + ), } diff --git a/.github/jsonnet/complete-workflows.jsonnet b/.github/jsonnet/complete-workflows.jsonnet index a9b18ad5..d930df02 100644 --- a/.github/jsonnet/complete-workflows.jsonnet +++ b/.github/jsonnet/complete-workflows.jsonnet @@ -1,5 +1,6 @@ local base = import 'base.jsonnet'; local misc = import 'misc.jsonnet'; +local pnpm = import 'pnpm.jsonnet'; local yarn = import 'yarn.jsonnet'; { @@ -11,15 +12,36 @@ local yarn = import 'yarn.jsonnet'; * 2. 'publish-prod' - Production package publishing on branch push * 3. 'pr' - Pull request preview publishing and testing * - * @param {array} [repositories=['gynzy']] - The repositories to publish to + * @param {array} [repositories=['github']] - The repositories to publish to * @param {boolean} [isPublicFork=true] - Whether the repository is a public fork (affects runner selection) * @param {boolean} [checkVersionBump=true] - Whether to assert if the version was bumped (recommended) * @param {jobs} [testJob=null] - A job to be run during PR to assert tests. Can be an array of jobs - * @param {string} [branch='main'] - The branch to run the publish-prod job on + * @param {string} [branch='main'] - The branch that triggers the publish-prod job; publishes the package specified in package.json and sets latest tag + * @param {string} [packageManager='yarn'] - Package manager to use ('yarn' or 'pnpm') + * @param {string} [image=null] - Docker image override for publish jobs; null uses the PM-specific default + * @param {array} [buildSteps=null] - Build steps override; null uses the PM-specific default. Pass `[]` to skip build. * @returns {workflows} - Complete set of GitHub Actions workflows for JavaScript package lifecycle */ - workflowJavascriptPackage(repositories=['gynzy'], isPublicFork=true, checkVersionBump=true, testJob=null, branch='main'):: + workflowJavascriptPackage( + repositories=['github'], + isPublicFork=true, + checkVersionBump=true, + testJob=null, + branch='main', + packageManager='yarn', + image='mirror.gcr.io/node:24', + buildSteps=null, + ):: local runsOn = (if isPublicFork then 'ubuntu-latest' else null); + local defaultBuildSteps = if packageManager == 'pnpm' then [base.step('build', 'pnpm run build')] + else [base.step('build', 'yarn build')]; + local effectiveBuildSteps = if buildSteps != null then buildSteps else defaultBuildSteps; + local publishJob = if packageManager == 'pnpm' + then pnpm.pnpmPublishJob(repositories=repositories, runsOn=runsOn, image=image, buildSteps=effectiveBuildSteps, publishBranch=branch) + else yarn.yarnPublishJob(repositories=repositories, runsOn=runsOn, image=image, buildSteps=effectiveBuildSteps, publishBranch=branch); + local previewJob = if packageManager == 'pnpm' + then pnpm.pnpmPublishPreviewJob(repositories=repositories, runsOn=runsOn, checkVersionBump=checkVersionBump, image=image, buildSteps=effectiveBuildSteps) + else yarn.yarnPublishPreviewJob(repositories=repositories, runsOn=runsOn, checkVersionBump=checkVersionBump, image=image, buildSteps=effectiveBuildSteps); base.pipeline( 'misc', @@ -27,16 +49,12 @@ local yarn = import 'yarn.jsonnet'; ) + base.pipeline( 'publish-prod', - [ - yarn.yarnPublishJob(repositories=repositories, runsOn=runsOn), - ], + [publishJob], event={ push: { branches: [branch] } }, ) + base.pipeline( 'pr', - [ - yarn.yarnPublishPreviewJob(repositories=repositories, runsOn=runsOn, checkVersionBump=checkVersionBump), - ] + + [previewJob] + (if testJob != null then [testJob] else []) diff --git a/.github/jsonnet/deployment.jsonnet b/.github/jsonnet/deployment.jsonnet index 61e066de..34d9d638 100644 --- a/.github/jsonnet/deployment.jsonnet +++ b/.github/jsonnet/deployment.jsonnet @@ -160,10 +160,11 @@ local notifications = import 'notifications.jsonnet'; * Generate a GitHub ifClause for the provided deployment targets. * * @param {array} targets - Array of deployment target environment names + * @param {boolean} [virkoOnly=true] - If true, also require the deployment event to be created by 'gynzy-virko', preventing manually created deployment events from triggering the job * @returns {string} - GitHub Actions conditional expression that matches any of the provided targets */ - deploymentTargets(targets):: - '${{ ' + std.join(' || ', std.map(function(target) "github.event.deployment.environment == '" + target + "'", targets)) + ' }}', + deploymentTargets(targets, virkoOnly=true):: + '${{ (' + std.join(' || ', std.map(function(target) "github.event.deployment.environment == '" + target + "'", targets)) + ')' + (if virkoOnly then " && github.event.deployment.creator.login == 'gynzy-virko'" else '') + ' }}', /** * Creates a step to update deployment status (success/failure) based on the result from the current job diff --git a/.github/jsonnet/helm.jsonnet b/.github/jsonnet/helm.jsonnet index 40befeca..e387cb49 100644 --- a/.github/jsonnet/helm.jsonnet +++ b/.github/jsonnet/helm.jsonnet @@ -1,6 +1,7 @@ local base = import 'base.jsonnet'; local clusters = import 'clusters.jsonnet'; local databases = import 'databases.jsonnet'; +local deployment = import 'deployment.jsonnet'; local images = import 'images.jsonnet'; local misc = import 'misc.jsonnet'; local services = import 'services.jsonnet'; @@ -151,7 +152,7 @@ local services = import 'services.jsonnet'; base.ghJob( 'deploy-prod', runsOn=runsOn, - ifClause="${{ github.event.deployment.environment == '" + environment + "' }}", + ifClause=deployment.deploymentTargets([environment]), image=image, useCredentials=useCredentials, steps=[ @@ -234,7 +235,7 @@ local services = import 'services.jsonnet'; base.ghJob( 'deploy-test', runsOn=runsOn, - ifClause="${{ github.event.deployment.environment == 'test' }}", + ifClause=deployment.deploymentTargets(['test']), image=image, useCredentials=useCredentials, steps=[ @@ -515,7 +516,7 @@ local services = import 'services.jsonnet'; runsOn=runsOn, image=image, useCredentials=useCredentials, - ifClause="${{ github.event.deployment.environment == 'canary' }}", + ifClause=deployment.deploymentTargets(['canary']), steps=[ misc.checkout(), self.helmDeployCanary( @@ -597,7 +598,7 @@ local services = import 'services.jsonnet'; base.ghJob( 'kill-canary', runsOn=runsOn, - ifClause="${{ github.event.deployment.environment == 'kill-canary' || github.event.deployment.environment == 'production' }}", + ifClause=deployment.deploymentTargets(['kill-canary', 'production']), image=images.default_job_image, useCredentials=false, steps=[ diff --git a/.github/jsonnet/images.jsonnet b/.github/jsonnet/images.jsonnet index c3ef14e4..def35f73 100644 --- a/.github/jsonnet/images.jsonnet +++ b/.github/jsonnet/images.jsonnet @@ -20,6 +20,7 @@ default_mongodb_image: 'europe-docker.pkg.dev/unicorn-985/private-images/docker-images_mongo8-replicated:v1', mongo_job_image: 'europe-docker.pkg.dev/unicorn-985/public-images/docker-images_mongo-cloner-job:v1', default_python_image: 'mirror.gcr.io/python:3.12.1', + cloud_sdk_image: 'europe-docker.pkg.dev/unicorn-985/private-images/docker-images_gcloud:v2', default_pulumi_node_image: 'mirror.gcr.io/node:22', job_poster_image: 'europe-docker.pkg.dev/unicorn-985/public-images/docker-images_job-poster:v2', } diff --git a/.github/jsonnet/misc.jsonnet b/.github/jsonnet/misc.jsonnet index 69be3a00..5603f26b 100644 --- a/.github/jsonnet/misc.jsonnet +++ b/.github/jsonnet/misc.jsonnet @@ -14,13 +14,22 @@ local images = import 'images.jsonnet'; * @param {string} [ref=null] - Specific git ref/branch/tag to checkout * @param {boolean} [preferSshClone=true] - Whether to attempt SSH clone first * @param {boolean} [includeSubmodules=true] - Whether to checkout git submodules + * @param {boolean} [blobless=null] - Whether to perform a blobless clone (--filter=blob:none); null uses default (false) + * @param {number} [retryAttempts=null] - Number of additional checkout attempts on failure; null uses default (0) + * @param {number} [cloneTimeout=null] - Timeout for git clone operation in minutes; null uses default (10) + * @param {boolean} [skipSeed=false] - Boolean where the archive based git initialization can be skipped * @returns {steps} - GitHub Actions steps for repository checkout */ - checkout(ifClause=null, fullClone=false, ref=null, preferSshClone=true, includeSubmodules=true):: + checkout(ifClause=null, fullClone=false, ref=null, preferSshClone=true, includeSubmodules=true, blobless=null, retryAttempts=null, cloneTimeout=null, skipSeed=false):: + local secret = self.secret; + local actualBlobless = if blobless == null then false else blobless; + local actualRetryAttempts = if retryAttempts == null then 0 else retryAttempts; + local actualCloneTimeout = if cloneTimeout == null then 10 else cloneTimeout; local with = (if fullClone then { 'fetch-depth': 0 } else {}) + (if ref != null then { ref: ref } else {}) + - (if includeSubmodules then { submodules: 'recursive' } else {}); + (if includeSubmodules then { submodules: 'recursive' } else {}) + + (if actualBlobless then { filter: 'blob:none' } else {}); local sshSteps = (if (preferSshClone) then base.step( 'check for ssh/git binaries', @@ -66,25 +75,75 @@ local images = import 'images.jsonnet'; id='check-binaries', ) else []); + // Cache seed: unpack the mirror archive (full working tree + .git) so the checkout + // below only fetches the delta. Skipped at runtime when the mirror secret is empty. + // Any failure leaves a clean workspace and continues normally. + local seedSteps = (if skipSeed then [] else base.step( + 'fetch git-mirror archive', + ||| + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + |||, + env={ GIT_HTTPS_ARCHIVE_MIRROR: secret('GIT_HTTPS_ARCHIVE_MIRROR') }, + ifClause="${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}", + shell='bash', + continueOnError=true, + )); + // strip the ${{ }} from the IfClause so we can inject and add our own if clause local localIfClause = (if ifClause == null then null else std.strReplace(std.strReplace(ifClause, '${{ ', ''), ' }}', '')); + local userIfPart = if ifClause == null then '' else '( ' + localIfClause + ' ) && '; + + // Generate `retryAttempts + 1` attempts of the same checkout action. Each non-final attempt + // sets continue-on-error so the workflow proceeds to the next attempt; retries are gated on + // the previous attempt's outcome being 'failure'. + local retrySteps(name, withParams, baseIf, idPrefix) = std.flatMap( + function(i) + local isLast = (i == actualRetryAttempts); + local previousFailed = if i == 0 then '' else " && steps." + idPrefix + (i - 1) + ".outcome == 'failure'"; + base.action( + name + (if i == 0 then '' else ' (retry ' + i + ')'), + actions.checkout_action, + with=withParams, + id=idPrefix + i, + ifClause='${{ ' + userIfPart + '( ' + baseIf + ' )' + previousFailed + ' }}', + timeoutMinutes=actualCloneTimeout, + continueOnError=(if isLast then null else true), + ), + std.range(0, actualRetryAttempts) + ); if (preferSshClone) then + seedSteps + sshSteps + - base.action( + retrySteps( 'Check out repository code via ssh', - actions.checkout_action, - with=with + (if preferSshClone then { 'ssh-key': '${{ secrets.VIRKO_GITHUB_SSH_KEY }}' } else {}), - ifClause='${{ ' + (if ifClause == null then '' else '( ' + localIfClause + ' ) && ') + " ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}", + with + { 'ssh-key': '${{ secrets.VIRKO_GITHUB_SSH_KEY }}' }, + "steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true'", + 'checkout-ssh-', ) + - base.action( + retrySteps( 'Check out repository code via https', - actions.checkout_action, - with=with, - ifClause='${{ ' + (if ifClause == null then '' else '( ' + localIfClause + ' ) && ') + " ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}", + with, + "steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false'", + 'checkout-https-', ) + base.step('git safe directory', "command -v git && git config --global --add safe.directory '*' || true") else + seedSteps + self.checkoutWithoutSshMagic(ifClause, fullClone, ref), /** diff --git a/.github/jsonnet/newrelic.jsonnet b/.github/jsonnet/newrelic.jsonnet index 660296f8..7bfc83de 100644 --- a/.github/jsonnet/newrelic.jsonnet +++ b/.github/jsonnet/newrelic.jsonnet @@ -1,4 +1,5 @@ local base = import 'base.jsonnet'; +local deployment = import 'deployment.jsonnet'; local images = import 'images.jsonnet'; local misc = import 'misc.jsonnet'; local yarn = import 'yarn.jsonnet'; @@ -10,7 +11,7 @@ local pnpm = import 'pnpm.jsonnet'; * * @param {array} apps - Array of application objects containing deployment information * @param {string} [cacheName=null] - Name of the cache to use for yarn/pnpm dependencies - * @param {string} [source='gynzy'] - Registry source ('gynzy' or 'github') for npm packages + * @param {string} [source='github'] - Registry source ('gynzy' or 'github') for npm packages * @param {string} [image='mirror.gcr.io/node:20.17'] - Docker image to use for the job * @param {boolean} [useCredentials=false] - Whether to use Docker registry credentials * @param {string} [packageManager='yarn'] - Package manager to use ('yarn' or 'pnpm') @@ -20,7 +21,7 @@ local pnpm = import 'pnpm.jsonnet'; postReleaseToNewRelicJob( apps, cacheName=null, - source='gynzy', + source='github', image='mirror.gcr.io/node:20.17', useCredentials=false, packageManager='yarn', @@ -31,7 +32,7 @@ local pnpm = import 'pnpm.jsonnet'; runsOn=runsOn, image=image, useCredentials=useCredentials, - ifClause="${{ github.event.deployment.environment == 'production' }}", + ifClause=deployment.deploymentTargets(['production']), steps= ( if packageManager == 'yarn' then diff --git a/.github/jsonnet/pnpm.jsonnet b/.github/jsonnet/pnpm.jsonnet index 632df9f4..fc38a6c5 100644 --- a/.github/jsonnet/pnpm.jsonnet +++ b/.github/jsonnet/pnpm.jsonnet @@ -1,6 +1,7 @@ local actions = import 'actions.jsonnet'; local base = import 'base.jsonnet'; local cache = import 'cache.jsonnet'; +local deployment = import 'deployment.jsonnet'; local misc = import 'misc.jsonnet'; local yarn = import 'yarn.jsonnet'; @@ -20,7 +21,9 @@ local yarn = import 'yarn.jsonnet'; base.action( 'Install pnpm tool', 'pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320', // v5 - with=with, + with=with + if workingDirectory != null then { + package_json_file: workingDirectory + '/package.json' + } else {}, ifClause=ifClause, ) + self.installPackages( @@ -60,9 +63,12 @@ local yarn = import 'yarn.jsonnet'; * @param {string} [ref=null] - Git ref to checkout (branch, tag, or commit) * @param {boolean} [prod=false] - Whether to install only production dependencies * @param {string} [workingDirectory=null] - Directory to run operations in - * @param {string} [source='gynzy'] - Registry source ('gynzy' or 'github') + * @param {string} [source='github'] - Registry source ('gynzy' or 'github') * @param {array} [pnpmInstallArgs=[]] - Additional arguments for pnpm install command * @param {boolean} [setupPnpm=true] - Whether to set up and install pnpm itself before installing all packages + * @param {boolean} [blobless=null] - Whether to perform a blobless clone (--filter=blob:none); null uses checkout default + * @param {number} [retryAttempts=null] - Number of additional checkout attempts on failure; null uses checkout default + * @param {number} [cloneTimeout=null] - Timeout for git clone operation in minutes; null uses checkout default * @returns {steps} - Array of step objects for the complete workflow */ checkoutAndPnpm( @@ -72,11 +78,14 @@ local yarn = import 'yarn.jsonnet'; ref=null, prod=false, workingDirectory=null, - source='gynzy', + source='github', pnpmInstallArgs=[], setupPnpm=true, + blobless=null, + retryAttempts=null, + cloneTimeout=null, ):: - misc.checkout(ifClause=ifClause, fullClone=fullClone, ref=ref) + + misc.checkout(ifClause=ifClause, fullClone=fullClone, ref=ref, blobless=blobless, retryAttempts=retryAttempts, cloneTimeout=cloneTimeout) + (if source == 'gynzy' then yarn.setGynzyNpmToken(ifClause=ifClause, workingDirectory=workingDirectory) else []) + (if source == 'github' then yarn.setGithubNpmToken(ifClause=ifClause, workingDirectory=workingDirectory) else []) + (if cacheName == null then [] else self.fetchPnpmCache(cacheName, ifClause=ifClause, workingDirectory=workingDirectory)) + @@ -122,9 +131,12 @@ local yarn = import 'yarn.jsonnet'; * @param {boolean} [setupPnpm=true] - Whether to set up and install pnpm itself before installing all packages * @param {string} [source=null] - Registry source ('gynzy' or 'github') * @param {string} [runsOn=null] - GitHub Actions runner to use for the job + * @param {boolean} [blobless=null] - Whether to perform a blobless clone (--filter=blob:none); null uses checkout default + * @param {number} [retryAttempts=null] - Number of additional checkout attempts on failure; null uses checkout default + * @param {number} [cloneTimeout=null] - Timeout for git clone operation in minutes; null uses checkout default * @returns {workflows} - Complete GitHub Actions pipeline configuration */ - updatePnpmCachePipeline(cacheName, appsDir='packages', image=null, useCredentials=null, setupPnpm=true, source=null, runsOn=null):: + updatePnpmCachePipeline(cacheName, appsDir='packages', image=null, useCredentials=null, setupPnpm=true, source=null, runsOn=null, blobless=null, retryAttempts=null, cloneTimeout=null):: base.pipeline( 'update-pnpm-cache', [ @@ -133,12 +145,15 @@ local yarn = import 'yarn.jsonnet'; runsOn=runsOn, image=image, useCredentials=useCredentials, - ifClause="${{ github.event.deployment.environment == 'production' || github.event.deployment.environment == 'prod' }}", + ifClause=deployment.deploymentTargets(['production']), steps=[ self.checkoutAndPnpm( cacheName=null, // to populate cache we want a clean install setupPnpm=setupPnpm, source=source, + blobless=blobless, + retryAttempts=retryAttempts, + cloneTimeout=cloneTimeout, ), base.action( 'setup auth', @@ -168,9 +183,13 @@ local yarn = import 'yarn.jsonnet'; * @param {array} [pnpmInstallArgs=[]] - Additional arguments for pnpm install * @param {string} [auditLevel='moderate'] - Minimum severity level to fail the job ('low', 'moderate', 'high', 'critical') * @param {string} [runsOn=null] - GitHub Actions runner to use for the job + * @param {string} [source='github'] - Where to install @gynzy packages from ('github', 'gynzy') + * @param {boolean} [blobless=null] - Whether to perform a blobless clone (--filter=blob:none); null uses checkout default + * @param {number} [retryAttempts=null] - Number of additional checkout attempts on failure; null uses checkout default + * @param {number} [cloneTimeout=null] - Timeout for git clone operation in minutes; null uses checkout default * @returns {workflows} - Complete GitHub Actions pipeline configuration */ - pnpmAuditPipeline(cacheName=null, image=null, setupPnpm=true, pnpmInstallArgs=[], auditLevel='moderate', runsOn=null):: + pnpmAuditPipeline(cacheName=null, image=null, setupPnpm=true, pnpmInstallArgs=[], auditLevel='moderate', runsOn=null, source=null, blobless=null, retryAttempts=null, cloneTimeout=null):: base.pipeline( 'pnpm-audit', [ @@ -184,6 +203,10 @@ local yarn = import 'yarn.jsonnet'; ref='${{ github.event.pull_request.head.sha }}', setupPnpm=setupPnpm, pnpmInstallArgs=pnpmInstallArgs, + source=source, + blobless=blobless, + retryAttempts=retryAttempts, + cloneTimeout=cloneTimeout, ), base.step('pnpm-audit', 'pnpm audit --audit-level=' + auditLevel), ], @@ -191,4 +214,164 @@ local yarn = import 'yarn.jsonnet'; ], event='pull_request', ), + + /** + * Creates a step to publish a package with pnpm, handling version/tag for PR, tag and branch builds. + * + * @param {boolean} [isPr=true] - Whether this is a PR build (affects versioning) + * @param {string} [ifClause=null] - Conditional expression to determine if step should run + * @param {string} [publishBranch=null] - The branch that triggers the publish-prod job; publishes the package specified in package.json and sets latest tag. When null, defaults to `main`/`master` + * @returns {steps} - Array containing a single step object + */ + pnpmPublish(isPr=true, ifClause=null, publishBranch=null):: + local branchCheck = + if publishBranch == null then + '( "${GITHUB_REF_NAME}" == "main" || "${GITHUB_REF_NAME}" == "master" )' + else + '"${GITHUB_REF_NAME}" == "' + publishBranch + '"'; + base.step( + 'publish', + ||| + bash -c 'set -xeo pipefail; + + cp package.json package.json.bak; + + VERSION=$(node -p "require(\"./package.json\").version"); + if [[ ! -z "${PR_NUMBER}" ]]; then + echo "Setting tag/version for pr build."; + TAG=pr-$PR_NUMBER; + PUBLISHVERSION="$VERSION-pr$PR_NUMBER.$GITHUB_RUN_NUMBER"; + elif [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then + if [[ "${GITHUB_REF_NAME}" != "${VERSION}" ]]; then + echo "Tag version does not match package version. They should match. Exiting"; + exit 1; + fi + echo "Setting tag/version for release/tag build."; + PUBLISHVERSION=$VERSION; + TAG="latest"; + elif [[ "${GITHUB_REF_TYPE}" == "branch" && %s ]] || [[ "${GITHUB_EVENT_NAME}" == "deployment" ]]; then + echo "Setting tag/version for release/tag build."; + PUBLISHVERSION=$VERSION; + TAG="latest"; + else + exit 1 + fi + + npm version --no-git-tag-version --allow-same-version "$PUBLISHVERSION"; + pnpm publish --no-git-checks --tag "$TAG"; + + mv package.json.bak package.json; + '; + ||| % branchCheck, + env={} + (if isPr then { PR_NUMBER: '${{ github.event.number }}' } else {}), + ifClause=ifClause, + ), + + /** + * Creates steps to publish a package to multiple repositories with pnpm. + * + * @param {boolean} isPr - Whether this is a PR build (affects versioning) + * @param {array} repositories - List of repository types ('gynzy' or 'github') + * @param {string} [ifClause=null] - Conditional expression to determine if steps should run + * @param {string} [publishBranch=null] - The branch that triggers the publish-prod job; publishes the package specified in package.json and sets latest tag. When null, defaults to `main`/`master` + * @returns {steps} - Array of step objects for publishing to all repositories + */ + pnpmPublishToRepositories(isPr, repositories, ifClause=null, publishBranch=null):: + (std.flatMap(function(repository) + if repository == 'gynzy' then [yarn.setGynzyNpmToken(ifClause=ifClause), self.pnpmPublish(isPr=isPr, ifClause=ifClause, publishBranch=publishBranch)] + else if repository == 'github' then [yarn.setGithubNpmToken(ifClause=ifClause, tokenSecret='GITHUB_TOKEN'), self.pnpmPublish(isPr=isPr, ifClause=ifClause, publishBranch=publishBranch)] + else error 'Unknown repository type given.', + repositories)), + + /** + * Creates a GitHub Actions job for publishing preview pnpm packages from PRs. + * + * @param {string} [image='node:24'] - Docker image to use for the job + * @param {boolean} [useCredentials=false] - Whether to use Docker registry credentials + * @param {string} [gitCloneRef='${{ github.event.pull_request.head.sha }}'] - Git reference to checkout + * @param {array} [buildSteps=null] - Build steps; null defaults to `[pnpm run build]`. Pass `[]` to skip build. + * @param {boolean} [checkVersionBump=true] - Whether to check if package version was bumped + * @param {array} [repositories=['github']] - List of repositories to publish to + * @param {boolean|string} [onChangedFiles=false] - Whether to only run on changed files (or glob pattern) + * @param {string} [changedFilesHeadRef=null] - Head reference for changed files comparison + * @param {string} [changedFilesBaseRef=null] - Base reference for changed files comparison + * @param {string} [runsOn=null] - Runner type to use + * @returns {jobs} - GitHub Actions job definition + */ + pnpmPublishPreviewJob( + image='mirror.gcr.io/node:24', + useCredentials=false, + gitCloneRef='${{ github.event.pull_request.head.sha }}', + buildSteps=null, + checkVersionBump=true, + repositories=['github'], + onChangedFiles=false, + changedFilesHeadRef=null, + changedFilesBaseRef=null, + runsOn=null, + ):: + local effectiveBuildSteps = if buildSteps == null then [base.step('build', 'pnpm run build')] else buildSteps; + local ifClause = (if onChangedFiles != false then "steps.changes.outputs.package == 'true'" else null); + base.ghJob( + 'pnpm-publish-preview', + runsOn=runsOn, + image=image, + useCredentials=useCredentials, + steps= + [self.checkoutAndPnpm(ref=gitCloneRef, fullClone=false, source=repositories[0], pnpmInstallArgs=['--frozen-lockfile'])] + + (if onChangedFiles != false then misc.testForChangedFiles({ package: onChangedFiles }, headRef=changedFilesHeadRef, baseRef=changedFilesBaseRef) else []) + + (if checkVersionBump then [ + base.action('check-version-bump', uses='del-systems/check-if-version-bumped@d5d13ffd75dc8aa9c2e1dca10d9bb27be10307b2', with={ // check-if-version-bumped@d5d13 == v2 + token: '${{ github.token }}', + }, ifClause=ifClause), + ] else []) + + (if onChangedFiles != false then std.map(function(step) std.map(function(s) s { 'if': ifClause }, step), effectiveBuildSteps) else effectiveBuildSteps) + + self.pnpmPublishToRepositories(isPr=true, repositories=repositories, ifClause=ifClause), + permissions={ packages: 'write', contents: 'read', 'pull-requests': 'read' }, + ), + + /** + * Creates a GitHub Actions job for publishing pnpm packages from main branch or releases. + * + * @param {string} [image='node:24'] - Docker image to use for the job + * @param {boolean} [useCredentials=false] - Whether to use Docker registry credentials + * @param {string} [gitCloneRef='${{ github.sha }}'] - Git reference to checkout + * @param {array} [buildSteps=null] - Build steps; null defaults to `[pnpm run build]`. Pass `[]` to skip build. + * @param {array} [repositories=['github']] - List of repositories to publish to + * @param {boolean|string} [onChangedFiles=false] - Whether to only run on changed files (or glob pattern) + * @param {string} [changedFilesHeadRef=null] - Head reference for changed files comparison + * @param {string} [changedFilesBaseRef=null] - Base reference for changed files comparison + * @param {string} [ifClause=null] - Conditional expression to determine if job should run + * @param {string} [runsOn=null] - Runner type to use + * @param {string} [publishBranch=null] - The branch that triggers the publish-prod job; publishes the package specified in package.json and sets latest tag. When null, defaults to `main`/`master` + * @returns {jobs} - GitHub Actions job definition + */ + pnpmPublishJob( + image='mirror.gcr.io/node:24', + useCredentials=false, + gitCloneRef='${{ github.sha }}', + buildSteps=null, + repositories=['github'], + onChangedFiles=false, + changedFilesHeadRef=null, + changedFilesBaseRef=null, + ifClause=null, + runsOn=null, + publishBranch=null, + ):: + local effectiveBuildSteps = if buildSteps == null then [base.step('build', 'pnpm run build')] else buildSteps; + local stepIfClause = (if onChangedFiles != false then "steps.changes.outputs.package == 'true'" else null); + base.ghJob( + 'pnpm-publish', + image=image, + runsOn=runsOn, + useCredentials=useCredentials, + steps= + [self.checkoutAndPnpm(ref=gitCloneRef, fullClone=false, source=repositories[0], pnpmInstallArgs=['--frozen-lockfile'])] + + (if onChangedFiles != false then misc.testForChangedFiles({ package: onChangedFiles }, headRef=changedFilesHeadRef, baseRef=changedFilesBaseRef) else []) + + (if onChangedFiles != false then std.map(function(step) std.map(function(s) s { 'if': stepIfClause }, step), effectiveBuildSteps) else effectiveBuildSteps) + + self.pnpmPublishToRepositories(isPr=false, repositories=repositories, ifClause=stepIfClause, publishBranch=publishBranch), + permissions={ packages: 'write', contents: 'read', 'pull-requests': 'read' }, + ifClause=ifClause, + ), } diff --git a/.github/jsonnet/pulumi.jsonnet b/.github/jsonnet/pulumi.jsonnet index 33ba2f8b..56128a69 100644 --- a/.github/jsonnet/pulumi.jsonnet +++ b/.github/jsonnet/pulumi.jsonnet @@ -1,5 +1,6 @@ local actions = import 'actions.jsonnet'; local base = import 'base.jsonnet'; +local deployment = import 'deployment.jsonnet'; local images = import 'images.jsonnet'; local misc = import 'misc.jsonnet'; local notifications = import 'notifications.jsonnet'; @@ -153,6 +154,9 @@ local pulumiDefaultEnvironment(stack) = { * @param {array} [additionalSetupSteps=[]] - Extra setup steps before Pulumi preview * @param {boolean} [ignoreEngines=false] - Whether to ignore Node.js engine requirements * @param {string} [runsOn=null] - GitHub Actions runner to use for the job + * @param {boolean} [blobless=null] - Whether to perform a blobless clone (--filter=blob:none); null uses checkout default + * @param {number} [retryAttempts=null] - Number of additional checkout attempts on failure; null uses checkout default + * @param {number} [cloneTimeout=null] - Timeout for git clone operation in minutes; null uses checkout default * @returns {jobs} - Complete GitHub Actions job for Pulumi preview */ pulumiPreviewJob( @@ -289,6 +293,9 @@ local pulumiDefaultEnvironment(stack) = { packageManager='yarn', pnpmInstallArgs=[], runsOn=null, + blobless=null, + retryAttempts=null, + cloneTimeout=null, ):: base.ghJob( 'pulumi-preview', @@ -297,8 +304,8 @@ local pulumiDefaultEnvironment(stack) = { useCredentials=false, steps=[ ( - if packageManager == 'yarn' then yarn.checkoutAndYarn(ref=gitCloneRef, cacheName=cacheName, fullClone=false, workingDirectory=yarnDir, source=yarnNpmSource, ignoreEngines=ignoreEngines) - else if packageManager == 'pnpm' then pnpm.checkoutAndPnpm(ref=gitCloneRef, cacheName=cacheName, fullClone=false, workingDirectory=yarnDir, source=yarnNpmSource, pnpmInstallArgs=pnpmInstallArgs) + if packageManager == 'yarn' then yarn.checkoutAndYarn(ref=gitCloneRef, cacheName=cacheName, fullClone=false, workingDirectory=yarnDir, source=yarnNpmSource, ignoreEngines=ignoreEngines, blobless=blobless, retryAttempts=retryAttempts, cloneTimeout=cloneTimeout) + else if packageManager == 'pnpm' then pnpm.checkoutAndPnpm(ref=gitCloneRef, cacheName=cacheName, fullClone=false, workingDirectory=yarnDir, source=yarnNpmSource, pnpmInstallArgs=pnpmInstallArgs, blobless=blobless, retryAttempts=retryAttempts, cloneTimeout=cloneTimeout) ), pulumiSetupSteps, additionalSetupSteps, @@ -326,6 +333,9 @@ local pulumiDefaultEnvironment(stack) = { * @param {string} [packageManager='yarn'] - Package manager to use ('yarn' or 'pnpm') * @param {array} [pnpmInstallArgs=[]] - Additional arguments for pnpm install * @param {string} [runsOn=null] - GitHub Actions runner to use for the job + * @param {boolean} [blobless=null] - Whether to perform a blobless clone (--filter=blob:none); null uses checkout default + * @param {number} [retryAttempts=null] - Number of additional checkout attempts on failure; null uses checkout default + * @param {number} [cloneTimeout=null] - Timeout for git clone operation in minutes; null uses checkout default * @returns {jobs} - GitHub Actions job for Pulumi deployment with failure notifications */ pulumiDeployJob( @@ -345,6 +355,9 @@ local pulumiDefaultEnvironment(stack) = { packageManager='yarn', pnpmInstallArgs=[], runsOn=null, + blobless=null, + retryAttempts=null, + cloneTimeout=null, ):: base.ghJob( name=jobName, @@ -354,8 +367,8 @@ local pulumiDefaultEnvironment(stack) = { useCredentials=false, steps=[ ( - if packageManager == 'yarn' then yarn.checkoutAndYarn(ref=gitCloneRef, cacheName=cacheName, fullClone=false, workingDirectory=yarnDir, source=yarnNpmSource, ignoreEngines=ignoreEngines) - else if packageManager == 'pnpm' then pnpm.checkoutAndPnpm(ref=gitCloneRef, cacheName=cacheName, fullClone=false, workingDirectory=yarnDir, source=yarnNpmSource, pnpmInstallArgs=pnpmInstallArgs) + if packageManager == 'yarn' then yarn.checkoutAndYarn(ref=gitCloneRef, cacheName=cacheName, fullClone=false, workingDirectory=yarnDir, source=yarnNpmSource, ignoreEngines=ignoreEngines, blobless=blobless, retryAttempts=retryAttempts, cloneTimeout=cloneTimeout) + else if packageManager == 'pnpm' then pnpm.checkoutAndPnpm(ref=gitCloneRef, cacheName=cacheName, fullClone=false, workingDirectory=yarnDir, source=yarnNpmSource, pnpmInstallArgs=pnpmInstallArgs, blobless=blobless, retryAttempts=retryAttempts, cloneTimeout=cloneTimeout) ), pulumiSetupSteps, additionalSetupSteps, @@ -374,12 +387,15 @@ local pulumiDefaultEnvironment(stack) = { * @param {string} [gitCloneRef='${{ github.sha }}'] - Git reference to checkout * @param {string} [cacheName=null] - Cache key for dependency caching * @param {string} [image=images.default_pulumi_node_image] - Container image - * @param {string} [ifClause="${{ github.event.deployment.environment == 'test' }}"] - Conditional for test deployments + * @param {string} [ifClause=deployment.deploymentTargets(['test'])] - Conditional for test deployments * @param {object} [environmentVariables={}] - Additional environment variables * @param {array} [additionalSetupSteps=[]] - Extra setup steps * @param {boolean} [ignoreEngines=false] - Whether to ignore Node.js engine requirements * @param {string} [packageManager='yarn'] - Package manager to use * @param {string} [runsOn=null] - GitHub Actions runner to use for the job + * @param {boolean} [blobless=null] - Whether to perform a blobless clone (--filter=blob:none); null uses checkout default + * @param {number} [retryAttempts=null] - Number of additional checkout attempts on failure; null uses checkout default + * @param {number} [cloneTimeout=null] - Timeout for git clone operation in minutes; null uses checkout default * @returns {jobs} - GitHub Actions job for test environment deployment */ pulumiDeployTestJob( @@ -390,12 +406,15 @@ local pulumiDefaultEnvironment(stack) = { gitCloneRef='${{ github.sha }}', cacheName=null, image=images.default_pulumi_node_image, - ifClause="${{ github.event.deployment.environment == 'test' }}", + ifClause=deployment.deploymentTargets(['test']), environmentVariables={}, additionalSetupSteps=[], ignoreEngines=false, packageManager='yarn', runsOn=null, + blobless=null, + retryAttempts=null, + cloneTimeout=null, ):: self.pulumiDeployJob( stack, @@ -411,6 +430,9 @@ local pulumiDefaultEnvironment(stack) = { additionalSetupSteps=additionalSetupSteps, ignoreEngines=ignoreEngines, packageManager=packageManager, + blobless=blobless, + retryAttempts=retryAttempts, + cloneTimeout=cloneTimeout, ), /** @@ -423,12 +445,15 @@ local pulumiDefaultEnvironment(stack) = { * @param {string} [gitCloneRef='${{ github.sha }}'] - Git reference to checkout * @param {string} [cacheName=null] - Cache key for dependency caching * @param {string} [image=images.default_pulumi_node_image] - Container image - * @param {string} [ifClause="${{ github.event.deployment.environment == 'prod' || github.event.deployment.environment == 'production' }}"] - Conditional for production deployments + * @param {string} [ifClause=deployment.deploymentTargets(['production'])] - Conditional for production deployments * @param {object} [environmentVariables={}] - Additional environment variables * @param {array} [additionalSetupSteps=[]] - Extra setup steps * @param {boolean} [ignoreEngines=false] - Whether to ignore Node.js engine requirements * @param {string} [packageManager='yarn'] - Package manager to use * @param {string} [runsOn=null] - GitHub Actions runner to use for the job + * @param {boolean} [blobless=null] - Whether to perform a blobless clone (--filter=blob:none); null uses checkout default + * @param {number} [retryAttempts=null] - Number of additional checkout attempts on failure; null uses checkout default + * @param {number} [cloneTimeout=null] - Timeout for git clone operation in minutes; null uses checkout default * @returns {jobs} - GitHub Actions job for production deployment */ pulumiDeployProdJob( @@ -439,12 +464,15 @@ local pulumiDefaultEnvironment(stack) = { gitCloneRef='${{ github.sha }}', cacheName=null, image=images.default_pulumi_node_image, - ifClause="${{ github.event.deployment.environment == 'prod' || github.event.deployment.environment == 'production' }}", + ifClause=deployment.deploymentTargets(['production']), environmentVariables={}, additionalSetupSteps=[], ignoreEngines=false, packageManager='yarn', runsOn=null, + blobless=null, + retryAttempts=null, + cloneTimeout=null, ):: self.pulumiDeployJob( stack, @@ -460,6 +488,9 @@ local pulumiDefaultEnvironment(stack) = { additionalSetupSteps=additionalSetupSteps, ignoreEngines=ignoreEngines, packageManager=packageManager, + blobless=blobless, + retryAttempts=retryAttempts, + cloneTimeout=cloneTimeout, ), /** @@ -540,6 +571,9 @@ local pulumiDefaultEnvironment(stack) = { * @param {array} [additionalSetupSteps=[]] - Extra setup steps for all jobs * @param {boolean} [ignoreEngines=false] - Whether to ignore Node.js engine requirements * @param {string} [runsOn=null] - GitHub Actions runner to use for the jobs + * @param {boolean} [blobless=null] - Whether to perform a blobless clone (--filter=blob:none); null uses checkout default + * @param {number} [retryAttempts=null] - Number of additional checkout attempts on failure; null uses checkout default + * @param {number} [cloneTimeout=null] - Timeout for git clone operation in minutes; null uses checkout default * @returns {workflows} - Complete set of Pulumi preview and deployment pipelines */ pulumiDefaultPipeline( @@ -556,6 +590,9 @@ local pulumiDefaultEnvironment(stack) = { additionalSetupSteps=[], ignoreEngines=false, runsOn=null, + blobless=null, + retryAttempts=null, + cloneTimeout=null, ):: base.pipeline( 'pulumi-preview', @@ -573,6 +610,9 @@ local pulumiDefaultEnvironment(stack) = { additionalSetupSteps=additionalSetupSteps, ignoreEngines=ignoreEngines, runsOn=runsOn, + blobless=blobless, + retryAttempts=retryAttempts, + cloneTimeout=cloneTimeout, ), ], ) + @@ -588,9 +628,12 @@ local pulumiDefaultEnvironment(stack) = { image=image, environmentVariables=environmentVariables, additionalSetupSteps=additionalSetupSteps, - ifClause=if deployTestWithProd then "${{ github.event.deployment.environment == 'test' || github.event.deployment.environment == 'prod' || github.event.deployment.environment == 'production' }}" else "${{ github.event.deployment.environment == 'test' }}", + ifClause=if deployTestWithProd then deployment.deploymentTargets(['test', 'production']) else deployment.deploymentTargets(['test']), ignoreEngines=ignoreEngines, runsOn=runsOn, + blobless=blobless, + retryAttempts=retryAttempts, + cloneTimeout=cloneTimeout, ), self.pulumiDeployProdJob( pulumiDir=pulumiDir, @@ -604,6 +647,9 @@ local pulumiDefaultEnvironment(stack) = { additionalSetupSteps=additionalSetupSteps, ignoreEngines=ignoreEngines, runsOn=runsOn, + blobless=blobless, + retryAttempts=retryAttempts, + cloneTimeout=cloneTimeout, ), ], event='deployment', diff --git a/.github/jsonnet/ruby.jsonnet b/.github/jsonnet/ruby.jsonnet index d19f2bf5..5ef7b32b 100644 --- a/.github/jsonnet/ruby.jsonnet +++ b/.github/jsonnet/ruby.jsonnet @@ -1,6 +1,7 @@ local actions = import 'actions.jsonnet'; local base = import 'base.jsonnet'; local database = import 'databases.jsonnet'; +local deployment = import 'deployment.jsonnet'; local docker = import 'docker.jsonnet'; local helm = import 'helm.jsonnet'; local misc = import 'misc.jsonnet'; @@ -150,7 +151,7 @@ local servicesImport = import 'services.jsonnet'; 'apidocs', runsOn=runsOn, image=rubyImageName, - ifClause="${{ github.event.deployment.environment == 'production' }}", + ifClause=deployment.deploymentTargets(['production']), steps=[ misc.checkout(), base.step( @@ -276,7 +277,7 @@ local servicesImport = import 'services.jsonnet'; base.ghJob( 'deploy-test', runsOn=runsOn, - ifClause="${{ github.event.deployment.environment == 'test' }}", + ifClause=deployment.deploymentTargets(['test']), image=image, useCredentials=useCredentials, steps= @@ -330,7 +331,7 @@ local servicesImport = import 'services.jsonnet'; base.ghJob( 'deploy-prod', runsOn=runsOn, - ifClause="${{ github.event.deployment.environment == 'production' }}", + ifClause=deployment.deploymentTargets(['production']), image=image, useCredentials=useCredentials, steps=[misc.checkout()] + diff --git a/.github/jsonnet/yarn.jsonnet b/.github/jsonnet/yarn.jsonnet index 6905ff2d..43bec7d2 100644 --- a/.github/jsonnet/yarn.jsonnet +++ b/.github/jsonnet/yarn.jsonnet @@ -1,6 +1,7 @@ local actions = import 'actions.jsonnet'; local base = import 'base.jsonnet'; local cache = import 'cache.jsonnet'; +local deployment = import 'deployment.jsonnet'; local misc = import 'misc.jsonnet'; { @@ -62,9 +63,10 @@ local misc = import 'misc.jsonnet'; * * @param {string} [ifClause=null] - Conditional expression to determine if step should run * @param {string} [workingDirectory=null] - Directory to create .npmrc file in + * @param {string} [tokenSecret='VIRKO_GITHUB_PKG_READONLY'] - Name of the secret holding the registry auth token. Defaults to a read-only token for installing packages; publish jobs pass a writable token (GITHUB_TOKEN). * @returns {steps} - Array containing a single step object */ - setGithubNpmToken(ifClause=null, workingDirectory=null):: + setGithubNpmToken(ifClause=null, workingDirectory=null, tokenSecret='VIRKO_GITHUB_PKG_READONLY'):: base.step( 'set github npm_token', run= @@ -76,7 +78,7 @@ local misc = import 'misc.jsonnet'; EOF |||, env={ - NODE_AUTH_TOKEN: misc.secret('GITHUB_TOKEN'), + NODE_AUTH_TOKEN: misc.secret(tokenSecret), }, ifClause=ifClause, workingDirectory=workingDirectory, @@ -91,12 +93,15 @@ local misc = import 'misc.jsonnet'; * @param {string} [ref=null] - Git ref to checkout (branch, tag, or commit) * @param {boolean} [prod=false] - Whether to install only production dependencies * @param {string} [workingDirectory=null] - Directory to run operations in - * @param {string} [source='gynzy'] - Registry source ('gynzy' or 'github') + * @param {string} [source='github'] - Registry source ('gynzy' or 'github') * @param {boolean} [ignoreEngines=false] - Whether to ignore engine version checks + * @param {boolean} [blobless=null] - Whether to perform a blobless clone (--filter=blob:none); null uses checkout default + * @param {number} [retryAttempts=null] - Number of additional checkout attempts on failure; null uses checkout default + * @param {number} [cloneTimeout=null] - Timeout for git clone operation in minutes; null uses checkout default * @returns {steps} - Array of step objects for the complete workflow */ - checkoutAndYarn(cacheName=null, ifClause=null, fullClone=false, ref=null, prod=false, workingDirectory=null, source='gynzy', ignoreEngines=false):: - misc.checkout(ifClause=ifClause, fullClone=fullClone, ref=ref) + + checkoutAndYarn(cacheName=null, ifClause=null, fullClone=false, ref=null, prod=false, workingDirectory=null, source='github', ignoreEngines=false, blobless=null, retryAttempts=null, cloneTimeout=null):: + misc.checkout(ifClause=ifClause, fullClone=fullClone, ref=ref, blobless=blobless, retryAttempts=retryAttempts, cloneTimeout=cloneTimeout) + (if source == 'gynzy' then self.setGynzyNpmToken(ifClause=ifClause, workingDirectory=workingDirectory) else []) + (if source == 'github' then self.setGithubNpmToken(ifClause=ifClause, workingDirectory=workingDirectory) else []) + (if cacheName == null then [] else self.fetchYarnCache(cacheName, ifClause=ifClause, workingDirectory=workingDirectory)) + @@ -139,7 +144,7 @@ local misc = import 'misc.jsonnet'; runsOn=runsOn, image=image, useCredentials=useCredentials, - ifClause="${{ github.event.deployment.environment == 'production' || github.event.deployment.environment == 'prod' }}", + ifClause=deployment.deploymentTargets(['production']), steps=[ misc.checkout() + self.setGynzyNpmToken() + @@ -168,9 +173,15 @@ local misc = import 'misc.jsonnet'; * * @param {boolean} [isPr=true] - Whether this is a PR build (affects versioning) * @param {string} [ifClause=null] - Conditional expression to determine if step should run + * @param {string} [publishBranch=null] - The branch that triggers the publish-prod job; publishes the package specified in package.json and sets latest tag. When null, defaults to `main`/`master` * @returns {steps} - Array containing a single step object */ - yarnPublish(isPr=true, ifClause=null):: + yarnPublish(isPr=true, ifClause=null, publishBranch=null):: + local branchCheck = + if publishBranch == null then + '( "${GITHUB_REF_NAME}" == "main" || "${GITHUB_REF_NAME}" == "master" )' + else + '"${GITHUB_REF_NAME}" == "' + publishBranch + '"'; base.step( 'publish', ||| @@ -191,7 +202,7 @@ local misc = import 'misc.jsonnet'; echo "Setting tag/version for release/tag build."; PUBLISHVERSION=$VERSION; TAG="latest"; - elif [[ "${GITHUB_REF_TYPE}" == "branch" && ( "${GITHUB_REF_NAME}" == "main" || "${GITHUB_REF_NAME}" == "master" ) ]] || [[ "${GITHUB_EVENT_NAME}" == "deployment" ]]; then + elif [[ "${GITHUB_REF_TYPE}" == "branch" && %s ]] || [[ "${GITHUB_EVENT_NAME}" == "deployment" ]]; then echo "Setting tag/version for release/tag build."; PUBLISHVERSION=$VERSION; TAG="latest"; @@ -203,7 +214,7 @@ local misc = import 'misc.jsonnet'; mv package.json.bak package.json; '; - |||, + ||| % branchCheck, env={} + (if isPr then { PR_NUMBER: '${{ github.event.number }}' } else {}), ifClause=ifClause, ), @@ -214,12 +225,13 @@ local misc = import 'misc.jsonnet'; * @param {boolean} isPr - Whether this is a PR build (affects versioning) * @param {array} repositories - List of repository types ('gynzy' or 'github') * @param {string} [ifClause=null] - Conditional expression to determine if steps should run + * @param {string} [publishBranch=null] - The branch that triggers the publish-prod job; publishes the package specified in package.json and sets latest tag. When null, defaults to `main`/`master` * @returns {steps} - Array of step objects for publishing to all repositories */ - yarnPublishToRepositories(isPr, repositories, ifClause=null):: + yarnPublishToRepositories(isPr, repositories, ifClause=null, publishBranch=null):: (std.flatMap(function(repository) - if repository == 'gynzy' then [self.setGynzyNpmToken(ifClause=ifClause), self.yarnPublish(isPr=isPr, ifClause=ifClause)] - else if repository == 'github' then [self.setGithubNpmToken(ifClause=ifClause), self.yarnPublish(isPr=isPr, ifClause=ifClause)] + if repository == 'gynzy' then [self.setGynzyNpmToken(ifClause=ifClause), self.yarnPublish(isPr=isPr, ifClause=ifClause, publishBranch=publishBranch)] + else if repository == 'github' then [self.setGithubNpmToken(ifClause=ifClause, tokenSecret='GITHUB_TOKEN'), self.yarnPublish(isPr=isPr, ifClause=ifClause, publishBranch=publishBranch)] else error 'Unknown repository type given.', repositories)), @@ -232,7 +244,7 @@ local misc = import 'misc.jsonnet'; * @param {string} [gitCloneRef='${{ github.event.pull_request.head.sha }}'] - Git reference to checkout * @param {array} [buildSteps=[base.step('build', 'yarn build')]] - Build steps to run before publishing * @param {boolean} [checkVersionBump=true] - Whether to check if package version was bumped - * @param {array} [repositories=['gynzy']] - List of repositories to publish to + * @param {array} [repositories=['github']] - List of repositories to publish to * @param {boolean|string} [onChangedFiles=false] - Whether to only run on changed files (or glob pattern) * @param {string} [changedFilesHeadRef=null] - Head reference for changed files comparison * @param {string} [changedFilesBaseRef=null] - Base reference for changed files comparison @@ -245,7 +257,7 @@ local misc = import 'misc.jsonnet'; gitCloneRef='${{ github.event.pull_request.head.sha }}', buildSteps=[base.step('build', 'yarn build')], checkVersionBump=true, - repositories=['gynzy'], + repositories=['github'], onChangedFiles=false, changedFilesHeadRef=null, changedFilesBaseRef=null, @@ -277,12 +289,13 @@ local misc = import 'misc.jsonnet'; * @param {boolean} [useCredentials=false] - Whether to use Docker registry credentials * @param {string} [gitCloneRef='${{ github.sha }}'] - Git reference to checkout * @param {array} [buildSteps=[base.step('build', 'yarn build')]] - Build steps to run before publishing - * @param {array} [repositories=['gynzy']] - List of repositories to publish to + * @param {array} [repositories=['github']] - List of repositories to publish to * @param {boolean|string} [onChangedFiles=false] - Whether to only run on changed files (or glob pattern) * @param {string} [changedFilesHeadRef=null] - Head reference for changed files comparison * @param {string} [changedFilesBaseRef=null] - Base reference for changed files comparison * @param {string} [ifClause=null] - Conditional expression to determine if job should run * @param {string} [runsOn=null] - Runner type to use + * @param {string} [publishBranch=null] - The branch that triggers the publish-prod job; publishes the package specified in package.json and sets latest tag. When null, defaults to `main`/`master` * @returns {jobs} - GitHub Actions job definition */ yarnPublishJob( @@ -290,12 +303,13 @@ local misc = import 'misc.jsonnet'; useCredentials=false, gitCloneRef='${{ github.sha }}', buildSteps=[base.step('build', 'yarn build')], - repositories=['gynzy'], + repositories=['github'], onChangedFiles=false, changedFilesHeadRef=null, changedFilesBaseRef=null, ifClause=null, runsOn=null, + publishBranch=null, ):: local stepIfClause = (if onChangedFiles != false then "steps.changes.outputs.package == 'true'" else null); base.ghJob( @@ -307,7 +321,7 @@ local misc = import 'misc.jsonnet'; [self.checkoutAndYarn(ref=gitCloneRef, fullClone=false)] + (if onChangedFiles != false then misc.testForChangedFiles({ package: onChangedFiles }, headRef=changedFilesHeadRef, baseRef=changedFilesBaseRef) else []) + (if onChangedFiles != false then std.map(function(step) std.map(function(s) s { 'if': stepIfClause }, step), buildSteps) else buildSteps) + - self.yarnPublishToRepositories(isPr=false, repositories=repositories, ifClause=stepIfClause), + self.yarnPublishToRepositories(isPr=false, repositories=repositories, ifClause=stepIfClause, publishBranch=publishBranch), permissions={ packages: 'write', contents: 'read', 'pull-requests': 'read' }, ifClause=ifClause, ), diff --git a/.github/workflows/Build Agent Images.yml b/.github/workflows/Build Agent Images.yml index 40dc835f..7396223d 100644 --- a/.github/workflows/Build Agent Images.yml +++ b/.github/workflows/Build Agent Images.yml @@ -6,6 +6,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -46,14 +68,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive" @@ -79,6 +105,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -119,14 +167,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive" @@ -153,6 +205,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -193,14 +267,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive" @@ -227,6 +305,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -267,14 +367,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive" @@ -301,6 +405,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -341,14 +467,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive" @@ -375,6 +505,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -415,14 +567,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive" @@ -449,6 +605,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -489,14 +667,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive" @@ -523,6 +705,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -563,14 +767,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive" diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7e08493f..9847ba81 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -6,6 +6,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -46,15 +68,19 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" @@ -81,6 +107,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -121,15 +169,19 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" @@ -157,6 +209,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -197,15 +271,19 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" @@ -233,6 +311,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -273,15 +373,19 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" @@ -309,6 +413,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -349,15 +475,19 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" @@ -385,6 +515,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -425,15 +577,19 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" @@ -461,6 +617,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -501,15 +679,19 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" @@ -537,6 +719,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -577,15 +781,19 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" @@ -611,6 +819,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -651,15 +881,19 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" @@ -684,6 +918,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -724,15 +980,19 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" @@ -757,6 +1017,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -797,14 +1079,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive" @@ -823,6 +1109,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -863,15 +1171,19 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ref": "${{ github.event.pull_request.head.sha || github.sha }}" @@ -896,6 +1208,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -936,14 +1270,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive" @@ -962,6 +1300,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -1002,14 +1362,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive" @@ -1028,6 +1392,28 @@ "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -1068,14 +1454,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive" diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 1f2c0466..1b533443 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -3,10 +3,32 @@ "deploy": "container": "image": "mirror.gcr.io/node:22" - "if": "${{ github.event.deployment.environment == 'production' }}" + "if": "${{ (github.event.deployment.environment == 'production') && github.event.deployment.creator.login == 'gynzy-virko' }}" "runs-on": - "ubuntu-latest" "steps": + - "continue-on-error": true + "env": + "GIT_HTTPS_ARCHIVE_MIRROR": "${{ secrets.GIT_HTTPS_ARCHIVE_MIRROR }}" + "if": "${{ env.GIT_HTTPS_ARCHIVE_MIRROR != '' }}" + "name": "fetch git-mirror archive" + "run": | + seed() { + if ! command -v zstd >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then apk add --no-cache zstd tar wget || return 1; + elif command -v apt >/dev/null 2>&1; then apt update && apt install -y zstd tar wget || return 1; + else return 1; fi + fi + wget -q -O - "$GIT_HTTPS_ARCHIVE_MIRROR" | tar -C "$GITHUB_WORKSPACE" --extract --zstd -f - || return 1 + } + if ! seed; then + echo "git-mirror seed failed; continuing with a clean checkout" + find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true + exit 1 + fi + echo "git-mirror seed succeeded" + exit 0 + "shell": "bash" - "id": "check-binaries" "name": "check for ssh/git binaries" "run": | @@ -47,14 +69,18 @@ fi; fi; echo "sshBinaryExists=false" >> $GITHUB_OUTPUT; - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" + - "id": "checkout-ssh-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'true' && steps.check-binaries.outputs.gitBinaryExists == 'true' ) }}" "name": "Check out repository code via ssh" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "ssh-key": "${{ secrets.VIRKO_GITHUB_SSH_KEY }}" "submodules": "recursive" - - "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" + - "id": "checkout-https-0" + "if": "${{ ( steps.check-binaries.outputs.sshBinaryExists == 'false' || steps.check-binaries.outputs.gitBinaryExists == 'false' ) }}" "name": "Check out repository code via https" + "timeout-minutes": 10 "uses": "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" "with": "submodules": "recursive"