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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github.jsonnet
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
local util = import '.github/jsonnet/index.jsonnet';

util.workflowJavascriptPackage(branch='main')
util.workflowJavascriptPackage(
repositories=['github', 'gynzy'],
packageManager='pnpm',
branch='main',
isPublicFork=true,
testJob=null,
)
2 changes: 1 addition & 1 deletion .github/jsonnet/GIT_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
aa305cb073663f1cc427017459aa90fa37127e4a
48fa11c3a7d9df1e16a1cf7e86505945b0b7b6a2
6 changes: 4 additions & 2 deletions .github/jsonnet/base.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 })
],
}
32 changes: 25 additions & 7 deletions .github/jsonnet/complete-workflows.jsonnet
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local base = import 'base.jsonnet';
local misc = import 'misc.jsonnet';
local pnpm = import 'pnpm.jsonnet';
local yarn = import 'yarn.jsonnet';

{
Expand All @@ -16,27 +17,44 @@ local yarn = import 'yarn.jsonnet';
* @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} [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=['gynzy'],
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)
else yarn.yarnPublishJob(repositories=repositories, runsOn=runsOn, image=image, buildSteps=effectiveBuildSteps);
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',
[misc.verifyJsonnet(fetch_upstream=false, runsOn=runsOn)],
) +
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 [])
Expand Down
47 changes: 37 additions & 10 deletions .github/jsonnet/misc.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@ 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)
* @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)::
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',
Expand Down Expand Up @@ -68,20 +75,40 @@ local images = import 'images.jsonnet';

// 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
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
Expand Down
Loading
Loading