qiwi / multi-semantic-release

Proof of concept that wraps semantic-release to work with monorepos.
BSD Zero Clause License
86 stars 34 forks source link

Subsequent releases are not tagged as latest #71

Closed GeeWizWow closed 2 years ago

GeeWizWow commented 2 years ago

Issue type

Not sure if this would be an issue with multi-semantic-release, or semantic-release, but have not observed it when using the latter.

Expected behavior

Publishing a new package, should result in it's GitHub release being tagged as latest.

Actual behavior

An older release is still tagged as latest

Steps to reproduce

  1. Create a new project, with one or more published workspaces, let multi-semantic-release create an initial 1.0.0 release for all workspaces.
  2. Add a commit to a single workspace, E.G. feat: blue
  3. Let multi-semantic-release create a new releases for the workspace.

Observe:

Demo:

https://github.com/GeeWizWow/multi-semrel

Screenshots:

image image

antongolub commented 2 years ago

Hey, @GeeWizWow,

I'm afraid, all packages of monorepo use the same release channel. Thus only one of them could be marked as the latest.

GeeWizWow commented 2 years ago

Hi @antongolub

In this case lib-b@1.1.0 was made after the 1.0.0 releases, in a separate "release cycle", but is still not marked as latest.

But... Having spent some time reading about tag and release sorting on github, it seems that this issue is widespread and affects anyone not using semver tags.

Going to close this as it's not an issue with multi-semantic-release and can most likely be fixed by using a different tagFormat

antongolub commented 2 years ago

That's interesting. In theory, it seems possible to use tags like v1.0.0+@scope/package-name. It should be semver compliant.

  1. Here's how semrel applies tagFormat option for tag parsing:

    const tagRegexp = `^${escapeRegExp(template(tagFormat)({version: ' '})).replace(' ', '(.+)')}`;
    
    return pReduce(
    branches,
    async (branches, branch) => {
      const branchTags = await pReduce(
        await getTags(branch.name, {cwd, env}),
        async (branchTags, tag) => {
          const [, version] = tag.match(tagRegexp) || [];
          return version && semver.valid(semver.clean(version))
            ? [...branchTags, {gitTag: tag, version, channels: (await getNote(tag, {cwd, env})).channels || [null]}]
            : branchTags;
        },
        []
      );
  2. semver validation regex: https://github.com/sindresorhus/semver-regex/blob/main/index.js#L2 UPD the regex looks broken. I've pushed the PR to fix: https://github.com/sindresorhus/semver-regex/pull/23

  3. perhaps we also need to tweak up a bit this piece of msr:

    const getVersionFromTag = (pkg, tag) => {
    if (!pkg.name) return tag || null;
    if (!tag) return null;
    
    const strMatch = tag.match(/[0-9].[0-9].[0-9].*/); // mb replace *./ ā†’ [^+]*
    return strMatch && strMatch[0] && semver.valid(strMatch[0]) ? strMatch[0] : null;
    };

Could you share the results of your experiments later?

GeeWizWow commented 2 years ago

Hey, @antongolub šŸ‘‹

It will be a couple of days before I can do any thorough testing, but from just a single quick and dirty test, it does look like using v${version}+${name} does sort the tags correctly. Have only done prereleases, so can't confirm if it fixes the issue with release ordering, but I'd imagine it does given tags are now sorting correctly.

FYI. I was attempting to set tagFormat as an option from the root package.json, and noticed it was being ignored, instead it's only picked up as a CLI arg, this may be expected, but for me it was contrary to expectations.

Does not work

root/
    package.json
        "release": {
            "tagFormat": "v${version}+${name}",
            ...
        }

Works

multi-semantic-release --tag-format='v${version}+${name}'