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

After merging the PR, npm i is not a no-op on package-lock.json #203

Open
glasser opened this issue Aug 13, 2022 · 11 comments
Open

After merging the PR, npm i is not a no-op on package-lock.json #203

glasser opened this issue Aug 13, 2022 · 11 comments

Comments

@glasser
Copy link
Contributor

glasser commented Aug 13, 2022

We use npm in our project. In a monorepo project, package-lock.json tends to contain some of the versions from the package itself. This means that after the action creates a PR and merges it, whenever you next run npm install you get a change to the package-lock.json that you need to push.

We're working around this to configure the action to run npm i after changeset version (see apollographql/apollo-server#6809). But maybe that should be the default? Or at least recommended in the docs for npm users?

@Andarist
Copy link
Member

I would like to have this fixed. The issue has been also noticed by other users. Part of the problem is that I don't think that we should be simply calling npm install as that could regenerate unrelated parts of the lockfle and covering up some accidental mistakes.

Thankfully the lockfile is just a JSON so it should be easy~ to:

  • load it
  • traverse & update it (it requires knowing the structure of the lockfile, but that should be pretty stable)
  • write it back

Ideally, we would like to avoid formatting changes while doing so. If I read things correctly then npm is using a simple util like this for writing JSONs back to disk: https://github.com/npm/cli/blob/9dc69830a5d78aa4042746d54e2a6b0d2af70caa/workspaces/libnpmversion/lib/write-json.js

This means that if we only detect the input indentation and the new line type then we should be able to replicate their logic very easily. We could still end up with formatting changes IF people reformat those files on their own (for instance by using Prettier or any other formatter) but I think that this is a secondary concern. This one can be just delegated to a precommit hook.

I would gladly accept a PR that would implement this 😉

@cacieprins
Copy link

This also breaks pnpm, if you use pnpm i --frozen-lockfile to install dependencies in your CI workflow :( because of the version updates after changeset version, the lockfile is out of date and pnpm throws an error.

@Andarist
Copy link
Member

@cacieprins is there a pnpm command that would update the lockfile with just the updated versions and nothing else? I would like to avoid introducing unrelated changes to lockfiles when versioning.

@cacieprins
Copy link

@Andarist no, unfortunately - running pnpm install after changeset version is the recommended path from them: https://pnpm.io/using-changesets

@Andarist
Copy link
Member

@zkochan are there any drawbacks to this approach? can the lockfile be accidentally updated in areas that shouldn't be affected? do you think that we should regenerate pnpm lockfile automatically when executing changeset version by calling pnpm install?

trevor-scheer added a commit to apollographql/federation that referenced this issue Jan 24, 2023
Known issue with changesets:
changesets/action#203
trevor-scheer added a commit to apollographql/federation that referenced this issue Jan 24, 2023
* Update package-lock.json

Known issue with changesets:
changesets/action#203

* implement workaround and update RELEASING doc
@yishayweb
Copy link

Hi guys
I'm using pnpm + changesets in a monorepo (with the changesets action) and I had the issue with the pnpm i --frozen-lockfile command on the CI (because on the CI pnpm i runs by default with the --frozen-lockfile flag)
The issue occured for me after updating two packages together where one is a peer dependency of the other
In this case, if p1 is a peer dependency of p2, then the versions pr would include an update of p1's version in p2's package.json, while the lock file still not updated. That's where things fail.

I didn't want to remove the --frozen-lockfile flag, so I tried another way.

I solved it by writing a seperate github action that checks if any 2 related packages (like p1 and p2) in the monorepo got updated, and if so, it runs an 'add' command
So if p1 is a dependency of p2, the github action runs pnpm --filter p2 add p1 --save-peer (or --save-dev or whatever type of dependency)
This fixes the lock file and then I'm commiting the fixed lock file to the versions pr. This way I don't need to fix it manually before merging

@Andarist would you consider including such a solution in the changeset action? (of course for all package managers)
If so, I'm willing to try and write something more generic so it would suite others needs

@Hainesy
Copy link

Hainesy commented Mar 8, 2023

@yishayweb would you consider sharing your github action so others can benefit from your hard work? 😊

@stefee
Copy link

stefee commented Mar 8, 2023

We encountered this issue and did the following to resolve it by adding a with: version: script which runs changeset version && npm install --package-lock-only.

Here's our full release.yml file (I've added comments to indicate which parts might not be needed):

name: Release

on:
  push:
    branches:
      - main

concurrency: ${{ github.workflow }}-${{ github.ref }}

jobs:
  release:
    name: Release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18.12.1 # optional

      - name: Install Dependencies
        run: npm ci
        env:
          NPM_AUTH: ${{ secrets.NPM_AUTH }} # optional

      - name: Create Release Pull Request
        uses: changesets/action@v1
        with:
          version: npm run version
          publish: npm run release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_AUTH: ${{ secrets.NPM_AUTH }} # optional

And here's our package.json scripts:

  "scripts": {
    "version": "changeset version && npm install --package-lock-only",
    "release": "changeset publish",

@yishayweb
Copy link

yishayweb commented Mar 12, 2023

Hi @Hainesy
This is the repo of the action
And this is an example of using it

Please note that it works now only with pnpm and that you need to pass the action the scope name of your packages, so if your package name is someScope@packageName you need to pass

with:
    packageScopeName: "someScope"

@mkurapov
Copy link

mkurapov commented Mar 24, 2023

Building on top of @stefee's answer: if you are using pnpm, the equivalent command would be:

"version": "pnpm changeset version && pnpm i --lockfile-only"

pnpm docs

@joshuajaco
Copy link

joshuajaco commented Oct 26, 2023

I'm so confused. Doesn't this mean the action is pretty much broken with the default config?

At the very least I'd expect this to be mentioned in the docs.

EDIT:

I was able to solve it by adding a "version-packages" script to package.json:

"version-packages": "changeset version && pnpm i --lockfile-only"

And then use it inside the GitHub action:

uses: changesets/action@v1
with:
  version: pnpm version-packages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants