Skip to content

Commit

Permalink
feat(workflow-files): leveraged workflows-core loader and dropeed dir…
Browse files Browse the repository at this point in the history
…ect js-yaml dependency
  • Loading branch information
travi committed Aug 26, 2024
1 parent 3f61c7f commit e87fe91
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 59 deletions.
21 changes: 11 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,9 @@
"dependencies": {
"@form8ion/config-file": "^1.0.1",
"@form8ion/core": "^4.6.1",
"@form8ion/github-workflows-core": "^5.1.0",
"@form8ion/github-workflows-core": "^5.3.0",
"@form8ion/javascript-core": "^11.0.0",
"deepmerge": "^4.2.2",
"js-yaml": "^4.1.0"
"deepmerge": "^4.2.2"
},
"devDependencies": {
"@babel/register": "7.24.6",
Expand All @@ -89,6 +88,7 @@
"gherkin-lint": "4.2.4",
"husky": "9.1.5",
"jest-when": "3.6.0",
"js-yaml": "4.1.0",
"lockfile-lint": "4.14.0",
"ls-engines": "0.9.3",
"mocha": "10.7.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {promises as fs} from 'fs';
import {load} from 'js-yaml';
import {fileExists} from '@form8ion/core';
import {loadWorkflowFile, workflowFileExists} from '@form8ion/github-workflows-core';

import scaffolder from './scaffolder.js';

Expand All @@ -10,26 +9,34 @@ function workflowPermissionsAreMinimal(existingContents) {
&& 'read' === existingContents.permissions.contents;
}

async function contentsNeedToBeUpdated(pathToReleaseWorkflowFile) {
const existingContents = load(await fs.readFile(pathToReleaseWorkflowFile, 'utf-8'));
async function contentsNeedToBeUpdated({projectRoot, name}) {
const existingContents = await loadWorkflowFile({projectRoot, name});

return existingContents.on.workflow_dispatch || !workflowPermissionsAreMinimal(existingContents);
}

async function releaseWorkflowShouldBeScaffolded(pathToReleaseWorkflowFile) {
return !await fileExists(pathToReleaseWorkflowFile) || contentsNeedToBeUpdated(pathToReleaseWorkflowFile);
async function releaseWorkflowShouldBeScaffolded({projectRoot, name}) {
return !await workflowFileExists({projectRoot, name}) || contentsNeedToBeUpdated({projectRoot, name});
}

export default async function ({projectRoot, nodeVersion}) {
async function renameLegacyReleaseWorkflow(projectRoot, experimentalReleaseWorkflowName) {
const workflowsDirectory = `${projectRoot}/.github/workflows`;
const pathToExperimentalReleaseWorkflowFile = `${workflowsDirectory}/experimental-release.yml`;
const pathToLegacyReleaseWorkflowFile = `${workflowsDirectory}/release.yml`;
const legacyReleaseWorkflowName = 'release';

if (await fileExists(pathToLegacyReleaseWorkflowFile)) {
await fs.rename(pathToLegacyReleaseWorkflowFile, pathToExperimentalReleaseWorkflowFile);
if (await workflowFileExists({projectRoot, name: legacyReleaseWorkflowName})) {
await fs.rename(
`${workflowsDirectory}/${legacyReleaseWorkflowName}.yml`,
`${workflowsDirectory}/${experimentalReleaseWorkflowName}.yml`
);
}
}

export default async function ({projectRoot, nodeVersion}) {
const experimentalReleaseWorkflowName = 'experimental-release';

await renameLegacyReleaseWorkflow(projectRoot, experimentalReleaseWorkflowName);

if (await releaseWorkflowShouldBeScaffolded(pathToExperimentalReleaseWorkflowFile)) {
if (await releaseWorkflowShouldBeScaffolded({projectRoot, name: experimentalReleaseWorkflowName})) {
return scaffolder({projectRoot, nodeVersion});
}

Expand Down
10 changes: 4 additions & 6 deletions src/semantic-release/ci-providers/github-workflows/lifter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import {promises as fs} from 'fs';
import {load} from 'js-yaml';
import {writeWorkflowFile} from '@form8ion/github-workflows-core';
import {loadWorkflowFile, writeWorkflowFile} from '@form8ion/github-workflows-core';

import determineTriggerNeedsFrom from './release-trigger-needs.js';
import {lift as liftReleaseWorkflow} from './experimental-release-workflow/index.js';
Expand All @@ -17,11 +15,11 @@ function removeCycjimmyActionFrom(otherJobs) {
}

export default async function ({projectRoot, nodeVersion}) {
const workflowsDirectory = `${projectRoot}/.github/workflows`;
const ciWorkflowName = 'node-ci';

await liftReleaseWorkflow({projectRoot, nodeVersion});

const parsedVerificationWorkflowDetails = load(await fs.readFile(`${workflowsDirectory}/node-ci.yml`, 'utf-8'));
const parsedVerificationWorkflowDetails = await loadWorkflowFile({projectRoot, name: ciWorkflowName});

parsedVerificationWorkflowDetails.on.push.branches = [
...parsedVerificationWorkflowDetails.on.push.branches.filter(branch => 'alpha' !== branch),
Expand All @@ -48,7 +46,7 @@ export default async function ({projectRoot, nodeVersion}) {

await writeWorkflowFile({
projectRoot,
name: 'node-ci',
name: ciWorkflowName,
config: parsedVerificationWorkflowDetails
});
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import {promises as fs} from 'fs';
import {fileExists} from '@form8ion/core';
import {loadWorkflowFile, workflowFileExists} from '@form8ion/github-workflows-core';

import {Given, Then} from '@cucumber/cucumber';
import {assert} from 'chai';
import {load} from 'js-yaml';

async function loadReleaseWorkflowDefinition() {
const experimentalReleaseWorkflowName = 'experimental-release';
const legacyReleaseWorkflowName = 'release';
const ciWorkflowName = 'node-ci';

async function loadReleaseWorkflowDefinition({projectRoot}) {
assert.isTrue(
await fileExists(`${process.cwd()}/.github/workflows/experimental-release.yml`),
'Release workflow is missing'
await workflowFileExists({projectRoot, name: experimentalReleaseWorkflowName}),
'Experimental-Release workflow is missing'
);

const {on: triggers, jobs} = load(
await fs.readFile(`${process.cwd()}/.github/workflows/experimental-release.yml`, 'utf-8')
);
const {on: triggers, jobs} = await loadWorkflowFile({projectRoot, name: experimentalReleaseWorkflowName});

return {triggers, jobs};
}
Expand Down Expand Up @@ -85,21 +86,21 @@ Given('no conventional verification workflow is defined', async function () {
});

Then('the experimental release workflow calls the reusable workflow for alpha branches', async function () {
const {triggers, jobs} = await loadReleaseWorkflowDefinition();
const {triggers, jobs} = await loadReleaseWorkflowDefinition({projectRoot: this.projectRoot});

assert.isUndefined(triggers.workflow_dispatch);
assert.deepEqual(triggers.push.branches, ['alpha']);
assert.equal(jobs.release.uses, 'form8ion/.github/.github/workflows/release-package.yml@master');
});

Then('the legacy experimental release workflow has been renamed', async function () {
assert.isFalse(await fileExists(`${process.cwd()}/.github/workflows/release.yml`));
assert.isFalse(await workflowFileExists({projectRoot: this.projectRoot, name: legacyReleaseWorkflowName}));
});

Then(
'the experimental release workflow calls the reusable workflow for semantic-release v19 for alpha branches',
async function () {
const {triggers, jobs} = await loadReleaseWorkflowDefinition();
const {triggers, jobs} = await loadReleaseWorkflowDefinition({projectRoot: this.projectRoot});

assert.isUndefined(triggers.workflow_dispatch);
assert.deepEqual(triggers.push.branches, ['alpha']);
Expand All @@ -111,14 +112,11 @@ Then(
);

Then('the release workflow is not defined', async function () {
assert.isFalse(await fileExists(`${process.cwd()}/.github/workflows/release.yml`));
assert.isFalse(await workflowFileExists({projectRoot: this.projectRoot, name: experimentalReleaseWorkflowName}));
});

Then('the verification workflow calls the reusable release workflow', async function () {
const verificationWorkflowDefinition = load(await fs.readFile(
`${process.cwd()}/.github/workflows/node-ci.yml`,
'utf-8'
));
const verificationWorkflowDefinition = await loadWorkflowFile({projectRoot: this.projectRoot, name: ciWorkflowName});
const branchTriggers = verificationWorkflowDefinition.on.push.branches;

assert.include(branchTriggers, 'master');
Expand Down Expand Up @@ -148,10 +146,7 @@ Then('the verification workflow calls the reusable release workflow', async func
});

Then('the verification workflow calls the reusable release workflow for semantic-release v19', async function () {
const verificationWorkflowDefinition = load(await fs.readFile(
`${process.cwd()}/.github/workflows/node-ci.yml`,
'utf-8'
));
const verificationWorkflowDefinition = await loadWorkflowFile({projectRoot: this.projectRoot, name: ciWorkflowName});
const branchTriggers = verificationWorkflowDefinition.on.push.branches;

assert.include(branchTriggers, 'master');
Expand All @@ -172,19 +167,13 @@ Then('the verification workflow calls the reusable release workflow for semantic
});

Then('the verification workflow does not trigger the release workflow', async function () {
const verificationWorkflowDefinition = load(await fs.readFile(
`${process.cwd()}/.github/workflows/node-ci.yml`,
'utf-8'
));
const verificationWorkflowDefinition = await loadWorkflowFile({projectRoot: this.projectRoot, name: ciWorkflowName});

assert.isUndefined(verificationWorkflowDefinition.jobs['trigger-release']);
});

Then('the release is not called until verification completes', async function () {
const verificationWorkflowDefinition = load(await fs.readFile(
`${process.cwd()}/.github/workflows/node-ci.yml`,
'utf-8'
));
const verificationWorkflowDefinition = await loadWorkflowFile({projectRoot: this.projectRoot, name: ciWorkflowName});
const triggerReleaseJob = verificationWorkflowDefinition.jobs.release;

assert.include(triggerReleaseJob.needs, 'verify');
Expand Down

0 comments on commit e87fe91

Please sign in to comment.