Skip to content

Commit

Permalink
fix: use correct paths for lib
Browse files Browse the repository at this point in the history
  • Loading branch information
tboerger committed Jun 4, 2024
1 parent 2b4a10c commit 1383d08
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 274 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: lts/*
cache: 'npm'
cache: "npm"

- name: Install dependencies
run: npm install --ci
Expand All @@ -41,5 +41,3 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.SEMANTIC_RELEASE_BOT_NPM_TOKEN }}
run: npx semantic-release

...
7 changes: 2 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: "${{ matrix.nodejs }}"
cache: 'npm'
cache: "npm"

- name: Install dependencies
run: npm install --ci
Expand All @@ -56,7 +56,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: 'npm'
cache: "npm"

- name: Install dependencies
run: npm install --ci
Expand All @@ -67,7 +67,6 @@ jobs:
- name: Execute tests
run: npm test


test-result:
runs-on: ubuntu-latest

Expand All @@ -85,5 +84,3 @@ jobs:
- name: Some matrix version failed
if: ${{ contains(needs.*.result, 'failure') }}
run: exit 1

...
File renamed without changes.
121 changes: 121 additions & 0 deletions lib/prepare.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import path from "node:path";
import { rename, readFile, writeFile } from "node:fs/promises";

import { execa } from "execa";
import { versionRegex } from "./common.js";

const writeVersion = async ({ versionFile, nextVersion, logger, cwd }) => {
const gemVersion = nextVersion.replace("-", ".");
const fullVersionPath = path.resolve(cwd, versionFile);
const versionContents = await readFile(fullVersionPath, "utf8");
const newContents = versionContents.replace(
versionRegex,
`$1${gemVersion}$2`,
);

logger.log("Writing version %s to `%s`", nextVersion, versionFile);

await writeFile(fullVersionPath, newContents, "utf8");

return { gemVersion };
};

const bundleInstall = async ({
updateGemfileLock,
cwd,
env,
logger,
stdout,
stderr,
}) => {
const command =
typeof updateGemfileLock === "string"
? updateGemfileLock
: "bundle install";

logger.log("Updating lock file with command `%s`", command);

const installResult = execa.command(command, { cwd, env });

installResult.stdout.pipe(stdout, { end: false });

installResult.stderr.pipe(stderr, { end: false });

await installResult;
};

const buildGem = async ({
gemspec,
gemName,
version,
cwd,
env,
logger,
stdout,
stderr,
}) => {
const gemFile = `${gemName}-${version}.gem`;

logger.log("Building gem `%s`", gemFile);

const buildResult = execa("gem", ["build", gemspec], { cwd, env });

buildResult.stdout.pipe(stdout, { end: false });

buildResult.stderr.pipe(stderr, { end: false });

await buildResult;

return gemFile;
};

export default async function prepare(
{ updateGemfileLock = false, gemFileDir = false },
{ nextRelease: { version }, cwd, env, logger, stdout, stderr },
{ versionFile, gemSpec, gemName },
) {
const { gemVersion } = await writeVersion({
versionFile,
nextVersion: version,
logger,
cwd,
});

if (updateGemfileLock) {
await bundleInstall({
updateGemfileLock,
cwd,
env,
logger,
stdout,
stderr,
});
}

let gemFile = await buildGem({
gemSpec,
gemName,
version: gemVersion,
cwd,
env,
logger,
stdout,
stderr,
});

if (gemFileDir) {
const gemFileSource = path.resolve(cwd, gemFile);

const gemFileDestination = path.resolve(cwd, gemFileDir.trim(), gemFile);

if (gemFileSource !== gemFileDestination) {
await rename(gemFileSource, gemFileDestination);
}

gemFile = path.join(gemFileDir.trim(), gemFile);
}

return {
gemFile,
};
}
36 changes: 36 additions & 0 deletions lib/publish.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { unlink } from "node:fs/promises";
import { execa } from "execa";

export default async function publish(
{ gemHost, gemPublish = true, gemFileDir = false },
{ cwd, env, logger, nextRelease: { version }, stdout, stderr },
{ gemFile, gemName, credentialsFile },
) {
if (gemPublish !== false) {
logger.log(`Publishing version ${version} to rubygems`);

const args = ["push", gemFile, "--config-file", credentialsFile];

if (gemHost) {
args.push("--host", gemHost);
}

const pushResult = execa("gem", args, { cwd, env });

pushResult.stdout.pipe(stdout, { end: false });

pushResult.stderr.pipe(stderr, { end: false });

await pushResult;

logger.log(`Published version ${version} of ${gemName} to rubygems`);
} else {
logger.log(
`Skip publishing to rubygems because gemPublish is ${gemPublish !== false}`,
);
}

if (gemFileDir === false) {
await unlink(gemFile);
}
}
85 changes: 32 additions & 53 deletions src/verify.js → lib/verify.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,52 @@
import path from 'node:path';
import { readFile, writeFile } from 'node:fs/promises';
import path from "node:path";
import { readFile, writeFile } from "node:fs/promises";

import { execa } from 'execa';
import { execa } from "execa";
import { SemanticReleaseError } from "@semantic-release/error";
import { glob } from 'glob'
import { versionRegex } from './common.js';
import { glob } from "glob";
import { versionRegex } from "./common.js";

const loadGemspec = async ({ cwd }) => {
const gemSpecs = await glob(
'*.gemspec',
{ cwd }
);
const gemSpecs = await glob("*.gemspec", { cwd });

if (gemSpecs.length !== 1) {
throw new SemanticReleaseError(
"Couldn't find a `.gemspec` file.",
'ENOGEMSPEC',
"ENOGEMSPEC",
`A single [.gemspec](https://guides.rubygems.org/specification-reference/) file in the root of your project is required to release a Rubygem.
Please follow the "[Make your own gem guide](https://guides.rubygems.org/make-your-own-gem/)" to create a valid \`.gemspec\` file
`,
);
}

const [
gemSpec
] = gemSpecs;
const [gemSpec] = gemSpecs;

let gemName = null;

try {
const { stdout } = await execa(
'ruby',
['-e', `puts Gem::Specification.load('${gemSpec}').name`],
"ruby",
["-e", `puts Gem::Specification.load('${gemSpec}').name`],
{ cwd },
);

gemName = stdout;
} catch (error) {
throw new SemanticReleaseError(
`Error loading \`${gemSpec}\``,
'EINVALIDGEMSPEC',
"EINVALIDGEMSPEC",
`A valid [.gemspec](https://guides.rubygems.org/specification-reference/) is required to release a Rubygem.
Please follow the "[Make your own gem guide](https://guides.rubygems.org/make-your-own-gem/)" to create a valid \`.gemspec\` file
`,
);
}

if (gemName === '') {
if (gemName === "") {
throw new SemanticReleaseError(
`Missing \`name\` attribute in \`${gemSpec}\``,
'ENOGEMNAME',
"ENOGEMNAME",
`The [name](https://guides.rubygems.org/specification-reference/#name) attribute is required in your \`.gemspec\` file in order to publish a Rubygem.
Please make sure to add a valid \`name\` for your gem in your \`.gemspec\`.
Expand All @@ -61,45 +56,34 @@ Please make sure to add a valid \`name\` for your gem in your \`.gemspec\`.

return {
name: gemName,
gemSpec
gemSpec,
};
};

const verifyVersionFile = async ({ cwd, versionGlob }) => {
const versionFiles = await glob(
versionGlob,
{ cwd }
);
const versionFiles = await glob(versionGlob, { cwd });

if (versionFiles.length !== 1) {
throw new SemanticReleaseError(
"Couldn't find a `version.lib` file.",
'ENOVERSIONFILE',
"ENOVERSIONFILE",
`A \`version.rb\` file in the \`lib/*\` dir of your project is required to release a Ruby gem.
Please create a \`version.rb\` file with a defined \`VERSION\` constant in your \`lib\` dir (or subdir).
`,
);
}

const [
versionFile
] = versionFiles;
const [versionFile] = versionFiles;

const fullVersionPath = path.resolve(
cwd,
versionFile
);
const fullVersionPath = path.resolve(cwd, versionFile);

const versionContents = await readFile(
fullVersionPath,
'utf8'
);
const versionContents = await readFile(fullVersionPath, "utf8");

if (!versionRegex.test(versionContents)) {
throw new SemanticReleaseError(
`Couldn't find a valid version constant defined in \`${versionFile}\`.`,
'EINVALIDVERSIONFILE',
"EINVALIDVERSIONFILE",
`Your \`version.rb\` file must define a \`VERSION\` constant.
Please define your gem's version a string constant named \`VERSION\` inside your \`version.rb\` file.
Expand All @@ -110,13 +94,11 @@ Please define your gem's version a string constant named \`VERSION\` inside your
return versionFile;
};

const verifyApiKey = async (
{ env, credentialsFile }
) => {
const verifyApiKey = async ({ env, credentialsFile }) => {
if (!env.GEM_HOST_API_KEY) {
throw new SemanticReleaseError(
'No rubygems API key specified.',
'ENOGEMAPIKEY',
"No rubygems API key specified.",
"ENOGEMAPIKEY",
`A rubygems API key must be created and set in the \`GEM_HOST_API_KEY\` environment variable on you CI environment.
You can retrieve an API key either from your \`~/.gem/credentials\` file or in your profile in [RubyGems.org](http://rubygems.org/).
Expand All @@ -127,36 +109,33 @@ You can retrieve an API key either from your \`~/.gem/credentials\` file or in y
await writeFile(
credentialsFile,
`---\n:rubygems_api_key: ${env.GEM_HOST_API_KEY}`,
'utf8',
"utf8",
);
};

export default async function verify(
{ versionGlob = 'lib/**/version.rb' },
{ versionGlob = "lib/**/version.rb" },
{ env, cwd },
{ credentialsFile }
{ credentialsFile },
) {
const {
name,
gemSpec
} = await loadGemspec({
cwd
const { name, gemSpec } = await loadGemspec({
cwd,
});

const versionFile = await verifyVersionFile({
cwd,
versionGlob
versionGlob,
});

await verifyApiKey({
env,
cwd,
credentialsFile
credentialsFile,
});

return {
gemName: name,
gemSpec,
versionFile
versionFile,
};
};
}
Loading

0 comments on commit 1383d08

Please sign in to comment.