qiwi / semantic-release-toolkit

Semantic release tools, plugins and configs for QIWI OSS projects
MIT License
11 stars 2 forks source link

How to build executables before semrel publishes new release? #164

Open padamstx opened 1 year ago

padamstx commented 1 year ago

Issue type

Background

The https://github.com/IBM/openapi-validator project uses semrel-toolkit's multi-semrel command to manage releases within the two packages contained in the project. We can successfully publish a new release of both packages when the commits indicate a new release is needed. In addition to the two npm packages that are published on npmjs.com, we also build executables for linux/macos/windows and these executables are published on our github project's "Releases" page as part of the release created by semrel. The problem is that our build (.travis.yml) is currently set up to build the executables prior to running semrel. This results in executables being published to github that do not reflect the new release that is created by semrel.

Question

What I think we need to do to fix this is to build the executables only AFTER semrel has created the new release and updated package.json with the new version #. But, I'm not sure how to make that happen while using semrel (or multi-semrel). Any ideas on how to fix this? Any help would be appreciated!

Thanks Phil

antongolub commented 1 year ago

@padamstx,

Seems you're looking for the https://github.com/semantic-release/exec plugin.

{
  "branches": "main",
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    "@semantic-release/changelog",
    ["@semantic-release/exec", {
      "prepare": "../../build.sh ${nextRelease.version} $(pwd) ...",
    }],
    "@semantic-release/npm",
    "@semantic-release/git",
    ["@semantic-release/github", {
      "assets": ["bin/*"]
    }]
  ]
}
padamstx commented 1 year ago

@antongolub Thanks for the tip. Do you know which semrel plugin updates the package.json file with the new release #? I just want to make sure I insert the exec plugin after that is all. Thanks again for the help!

antongolub commented 1 year ago

By default semrel uses the npm plugin for pkg version bumping and publishing.

prepare https://github.com/semantic-release/npm/blob/master/index.js#L68

async function prepare(pluginConfig, context) {
  const errors = verified ? [] : verifyNpmConfig(pluginConfig);

  setLegacyToken(context);

  try {
    // Reload package.json in case a previous external step updated it
    const pkg = await getPkg(pluginConfig, context);
    if (!verified && pluginConfig.npmPublish !== false && pkg.private !== true) {
      await verifyNpmAuth(npmrc, pkg, context);
    }
  } catch (error) {
    errors.push(...error);
  }

  if (errors.length > 0) {
    throw new AggregateError(errors);
  }

  await prepareNpm(npmrc, pluginConfig, context);
  prepared = true;
}

https://github.com/semantic-release/npm/blob/master/lib/prepare.js#L12

  const versionResult = execa(
    'npm',
    ['version', version, '--userconfig', npmrc, '--no-git-tag-version', '--allow-same-version'],
    {
      cwd: basePath,
      env,
      preferLocal: true,
    }
  );

publish https://github.com/semantic-release/npm/blob/master/lib/publish.js#L23

    logger.log(`Publishing version ${version} to npm registry on dist-tag ${distTag}`);
    const result = execa(
      'npm',
      ['publish', basePath, '--userconfig', npmrc, '--tag', distTag, '--registry', registry],
      {cwd, env, preferLocal: true}
    );
    result.stdout.pipe(stdout, {end: false});
    result.stderr.pipe(stderr, {end: false});