Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for lerna specific lifecycle scripts #643

Closed
bcoe opened this Issue Mar 6, 2017 · 9 comments

Comments

Projects
None yet
4 participants
@bcoe
Copy link
Contributor

bcoe commented Mar 6, 2017

To be able to plugin third-party tools with lerna, e.g., conventional-changelog generation, it would be awesome to have a few lerna-specific lifecycle scirpts fire in each package being managed.

For my specific use-case I'm picturing adding scripts to the inner-package.jsons that look something like this:

{
  "scripts": {
    "pretag": "fire changelog generation before the new tag is added",
    "posttag": "maybe do something after a git tag is added?"
  }
}

@bcoe bcoe referenced this issue Mar 6, 2017

Closed

make conventional-changelog play nicely with lerna #168

4 of 4 tasks complete
@evocateur

This comment has been minimized.

Copy link
Member

evocateur commented Mar 7, 2017

We're basically discussing a plugin system of sorts, yes? This is pretty exciting, and pretty daunting.

Exciting: this could be the way forward to allow all sorts of edge-casey options (version decisions in CI, lifecycle hooks, etc) to live in plugins instead of (further) complicating an already-complex codebase.

Daunting: Figuring that all out in a way that doesn't totally break our current panoply of options and gnarlytotally rad callback salad.

that being said...

lerna currently supports synchronous scripts/{pre,post}publish.js per-package lifecycle scripts, which as far as I can tell were historically used to do things that normal npm {pre,post}publish lifecycle scripts weren't able to accomplish(?).

Unfortunately for this integration, the current pre/postpublish are called well after the git operations (except the final git push --tags origin, confusingly). Would similar scripts/pretag.js and scripts/posttag.js executions inside the commitAndTagUpdates() method be sufficient?

Independent Versioning:

   gitCommitAndTagVersionForUpdates() {
+    this.updates.forEach((update) => this.execScript(update.package, "pretag"));
+
     const tags = this.updates.map((update) => `${update.package.name}@${this.updatesVersions[update.package.name]}`);
     const message = this.flags.message || tags.reduce((msg, tag) => msg + `${EOL} - ${tag}`, `Publish${EOL}`);
 
     GitUtilities.commit(message);
     tags.forEach(GitUtilities.addTag);
+
+    this.updates.forEach((update) => this.execScript(update.package, "posttag"));
+
     return tags;
   }

Fixed Versioning:

   gitCommitAndTagVersion(version) {
+    this.updates.forEach((update) => this.execScript(update.package, "pretag"));
+
     const tag = "v" + version;
     const message = this.flags.message || tag;
     GitUtilities.commit(message);
     GitUtilities.addTag(tag);
+
+    this.updates.forEach((update) => this.execScript(update.package, "posttag"));
+
     return tag;
   }

(or like, make yet another method or two to encapsulate the repetition...)

@bcoe

This comment has been minimized.

Copy link
Contributor Author

bcoe commented Mar 7, 2017

@evocateur thinking from the point of view of the upstream conventional-changelog ecosystem (basically a set of tools for figuring out version bumps and changelogs from digging through git-history) -- I think having a hook point before and after tagging, and allowing the tagging process to be overridden, would add a lot of power.

The workflow for independent mode feels sub-optimal right now, one needs to remember which libraries had patch updates, feature updates, major updates., etc; which is exactly the problem that tools like lerna, semantic-release, and conventional-changelog are trying to simplify for people.

@evocateur

This comment has been minimized.

Copy link
Member

evocateur commented Mar 7, 2017

Indeed, I agree. My diffs were just spitballing the "lowest-impact" solution, but I'm not particularly wedded to them. There's a fair amount of refactoring involved with any solution, and I would like to get to a place where we can let computers make decisions for us.

@bcoe

This comment has been minimized.

Copy link
Contributor Author

bcoe commented Mar 15, 2017

capturing an idea here:

perhaps the pretag lifecycle script could return a proposed version bump, in which case (in independent mode) a user wouldn't be prompted regarding the version bump.

@evocateur

This comment has been minimized.

Copy link
Member

evocateur commented Mar 15, 2017

Spitballing the interface in lerna.json, using npm scripts as a guide:

{
  "lerna": "2.0.0-beta.38",
  "lifecycle": {
    "version": "conventional-recommended-bump -p angular",
    "pretag": "conventional-changelog -p angular"
  },
  "packages": [
    "packages/*"
  ],
  "version": "independent"
}

Just like npm scripts, preversion and version run before the version is bumped. We overload it only slightly by making the return value of the version script override the prompting.

pretag I'm a little more ambivalent about, since we don't really want to expose the generation of a tagname in the tag phase (or do we?). Perhaps consistency really is a hobgoblin in this case.

The simplest way to pass the important bits of information (the package name, location, and current version) would be ye olde -- followed by positional args <packageName> <location> <currentVersion>. Unless we can get away with just passing the packageJsonLocation and assuming the tool can read it and make intelligent decisions from that point forward?

This spitballing doesn't work 100% with the current CLI API of conventional-changelog and conventional-recommended-bump, but it feels more robust long-term than some sort of rickety argument interpolation or (worse?) env var scheme*.

  • npm does this with various npm_* prefixed env vars. Maybe robust enough?
{
  "lifecycle": {
    "version": "conventional-recommended-bump -p angular -l ${LERNA_PACKAGE_NAME} --commit-path ${LERNA_PACKAGE_LOCATION}",
    "pretag": "conventional-changelog -p angular -l ${LERNA_PACKAGE_NAME} --commit-path ${LERNA_PACKAGE_LOCATION} --pkg ${LERNA_PACKAGE_MANIFEST}"
  }
}
@vovaguguiev

This comment has been minimized.

Copy link
Contributor

vovaguguiev commented Mar 21, 2017

@evocateur in my opinion, these lifecycle hooks should be overridable on the level of each package.
With the proposed approach is it still possible, but not very user-friendly:

{
  "lifecycle": {
    "pretag": "cd ${LERNA_PACKAGE_LOCATION} && npm run mypretag"   # will fail if there is no "mypretag" script
  }
}

Maybe we should run the lifecycle hooks already in the package directory and use name of an NPM script as a config option:

{
  "lifecycle": {
    "pretag": "mypretag"  # default value is "pretag"
  }
}

We can still inject the ENV variable in there and we can also check if the script with this name is actually present in the package.json and use standard behaviour (e.g. prompt for the version) if not.

Regarding the naming of the hooks, please be aware of this potential issue in case of using preXXX and postXXX names.

@lili21

This comment has been minimized.

Copy link

lili21 commented Aug 27, 2018

any update ?

@bcoe

This comment has been minimized.

Copy link
Contributor Author

bcoe commented Dec 24, 2018

I still think this is an good feature idea, unfortunately I don't think either @evocateur or I have had enough open-source cycles to move it along.

@dpaez dpaez referenced this issue Jan 28, 2019

Closed

npm login issue #37

@stale

This comment has been minimized.

Copy link

stale bot commented Feb 22, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Feb 22, 2019

@stale stale bot closed this Mar 1, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.