renovatebot / renovate

Home of the Renovate CLI: Cross-platform Dependency Automation by Mend.io
https://mend.io/renovate
GNU Affero General Public License v3.0
16.52k stars 2.12k forks source link

PostUpgradeTasks: Support binarySource=docker/install #8111

Open Chumper opened 3 years ago

Chumper commented 3 years ago

What Renovate type, platform and version are you using?

GHE Self hosted

{
  "renovateVersion": "24.10.1"
}

Describe the request

When setting the constraint in the config like this

    "force": {
        "constraints": {
            "node": "< 13.0.0"
        }
    }

then Renovate should respect this constraint during the execution of the postUpgrade tasks.

The underlying problem is that one repo still uses Node 12.X and lockfile updates are failing after the Renovate docker image updated the Version to 14.X: https://github.com/renovatebot/docker-renovate/pull/55

{
  "branch": "renovate/babel-monorepo",
  "dep": "@babel/core",
  "cmd": "node common/scripts/install-run-rush.js update",
  "stdout": "The rush.json configuration requests Rush version 5.30.1\nCopying /var/jenkins/renovate/repos/github/my/repo/common/config/rush/.npmrc --> /var/jenkins/renovate/repos/github/my/repo/common/temp/install-run/@microsoft+rush@5.30.1/.npmrc\nInstalling @microsoft/rush...\nadded 12 packages from 12 contributors and audited 32 packages in 5.739s\n\n15 packages are looking for funding\n  run `npm fund` for details\n\nfound 1 low severity vulnerability\n  run `npm audit fix` to fix them, or `npm audit` for details\nSuccessfully installed @microsoft/rush@5.30.1\n\nInvoking \"rush update\"\n----------------------\n\n\n\nRush Multi-Project Build Tool 5.30.1 - https://rushjs.io\nNode.js version is 14.15.3 (LTS)\n\n\n",
  "stderr": "npm notice created a lockfile as package-lock.json. You should commit this file.\n\nERROR: Your dev environment is running Node.js version v14.15.3 which does not\nmeet the requirements for building this repository.  (The rush.json\nconfiguration requires nodeSupportedVersionRange=\">=12.18.0 <13.0.0\")\n"
}

To Reproduce

Have a rush.json file with the following constraint: "nodeSupportedVersionRange": ">=12.18.0 <13.0.0", Then run the following in a postUpgradeTask: node common/scripts/install-run-rush.js update Additional context

The problem should be solved when we apply the same restriction of the postUpdate tasks to the postUpgrade tasks.

viceice commented 3 years ago

Can you build a small public reproduction repo. So we can debug this.

It's also important how are you running renovate. Currently only binarySource=docker is able to respect constraints.

viceice commented 3 years ago

I've checked the code now. So currently the postUpgrade tasks are run as direct child without any docker container.

It also don't have any concept of constraints, so it's not easy to apply them to postUpgrade

https://github.com/renovatebot/renovate/blob/62c68d07e31624d838fb4692c18fca802b3587b6/lib%2Fworkers%2Fbranch%2Findex.ts#L380-L382

rarkins commented 3 years ago

Even when binary mode is Docker?

viceice commented 3 years ago

yes, as we don't pass any docker args to exec

checked here: https://github.com/renovatebot/renovate/blob/5d99ff9862bac803dcea4e6ded5f3fec34abccfc/lib%2Futil%2Fexec%2Findex.ts#L126-L141

rarkins commented 3 years ago

Maybe we can use node:14 to at least let it run in Docker. Then maybe a new admin option of allowed image patterns plus configurable image in the user config

viceice commented 3 years ago

sounds good, but we should use renovate/node:14

HonkingGoose commented 3 years ago

I think we can label this status:ready now? We seem to have decided on a course of action?

yes, as we don't pass any docker args to exec

Maybe we can use node:14 to at least let it run in Docker. Then maybe a new admin option of allowed image patterns plus configurable image in the user config

sounds good, but we should use renovate/node:14

rarkins commented 3 years ago

When I read the above I'm still not sure exactly what needs to be done, and we don't have a reproduction repo either. So I think leave it as requirements

github-actions[bot] commented 3 years ago

Hi there,

The Renovate team needs your help! To fix the problem, we first need to know exactly what's causing the bug. A minimal reproduction help us to pinpoint the exact cause of the bug.

To get started, please read our guide on minimal reproductions to understand what is needed.

We may close the issue if you have not provided a minimal reproduction within two weeks. If you need more time, or are stuck, please ask for help or more time in a comment.

Good luck,

The Renovate team

jmccann commented 2 years ago

We are running into a similar issue.

This issue talks about the fact that renovate itself is running fine. They have constraints in their package.json that sets node < 13.0.0. This still works because during upgrade renovate is able to detect and use an appropriate node verison.

However, if trying to run a PostUpgradeTask then the version of node bundled in the renovate/renovate docker image is used. Right now its 14.x. So whatever script they are trying to run which seems does some stuff with deps as well fails because it sees node 14.x but requires node < 13.0.0.

For us, we have a project with constraints >=16 for node. So when we run our post upgrade script to do some dependency massaging we get errors Error: Command failed with exit code 1: yarn add --dev @babel/core@^7.0.0\nerror <some-internal-pacakge>@1.17.6: The engine \"node\" is incompatible with this module. Expected version \">=16\". Got \"14.18.2\".

So what is needed is either:

Having said all that, I'll see if I can provide something to reproduce today as well.

jmccann commented 2 years ago

Here is a reproduction repo I created: https://github.com/jmccann/renovate-post-upgrade-constraints

When I ran renovate against it (using renovate/renovate:32.99) this is what I saw:

DEBUG: Executing post-upgrade task (repository=jmccann/renovate-post-upgrade-constraints, branch=renovate/rimraf-3.x)
       "dep": "rimraf",
       "cmd": "yarn post-upgrade"
DEBUG: Executing command (repository=jmccann/renovate-post-upgrade-constraints, branch=renovate/rimraf-3.x)
       "dep": "rimraf",
       "command": "yarn post-upgrade"
DEBUG: rawExec err (repository=jmccann/renovate-post-upgrade-constraints, branch=renovate/rimraf-3.x)
       "dep": "rimraf",
       "err": {
         "killed": false,
         "code": 1,
         "signal": null,
         "cmd": "yarn post-upgrade",
         "stdout": "yarn run v1.22.19\ninfo Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.\n",
         "stderr": "warning package.json: No license field\nerror renovate-post-upgrade-constraints@0.0.1: The engine \"node\" is incompatible with this module. Expected version \">=16\". Got \"14.19.3\"\nerror Commands cannot run with an incompatible environment.\n",
         "message": "Command failed: yarn post-upgrade\nwarning package.json: No license field\nerror renovate-post-upgrade-constraints@0.0.1: The engine \"node\" is incompatible with this module. Expected version \">=16\". Got \"14.19.3\"\nerror Commands cannot run with an incompatible environment.\n",
         "stack": "Error: Command failed: yarn post-upgrade\nwarning package.json: No license field\nerror renovate-post-upgrade-constraints@0.0.1: The engine \"node\" is incompatible with this module. Expected version \">=16\". Got \"14.19.3\"\nerror Commands cannot run with an incompatible environment.\n\n    at ChildProcess.exithandler (child_process.js:383:12)\n    at ChildProcess.emit (events.js:400:28)\n    at ChildProcess.emit (domain.js:475:12)\n    at maybeClose (internal/child_process.js:1088:16)\n    at Process.ChildProcess._handle.onexit (internal/child_process.js:296:5)"
       }
viceice commented 2 years ago

Idea:

Allow configure tools (like we do in manager artifact update) on postupdateconfig object. Thsat ways we can simply validate and pass through known tools and install them before running post update task. As first step user needs to manualls configure tool name and version. Later we can try to detect the version required.

WarpRat commented 1 year ago

Before I found this issue, I was looking through the code to see how difficult it would be to add an option to run postUgradeTasks in the renovate child container if the executionMode is set to update and renovate is using the docker binary source for the dependency. I'll try to find time to get a minimal demo of that working. Having the binarySource option available in postUpgradeTasks would be great but this option may be a quicker intermediate step.

viceice commented 1 year ago

i think we can allow toolConstraints on post update tasks and renovate should use those on binarySource=docker/install. on binarySource=docker we should run those in our sidecar docker image.

https://github.com/renovatebot/renovate/blob/0e43f41da61009073b7c9dac766b38d5d3b6dc14/lib/modules/manager/npm/post-update/yarn.ts#L188

Hackwar commented 1 year ago

We ran into the same issue (#17994) in our renovatebot instance we are running for Joomla. (https://github.com/joomla/joomla-cms/)

rarkins commented 1 year ago

@Hackwar are you self-hosting? If so, can you describe specifically how? e.g. using slim image and binarySource=docker ?

Hackwar commented 1 year ago

How we run renovate in our script:

docker run \
    --rm \
    -e RENOVATE_TOKEN \
    -e RENOVATE_FORK_TOKEN="$RENOVATE_TOKEN" \
    -e RENOVATE_DOCKER_USER="1000:0" \
    -v /run/docker.sock:/var/run/docker.sock \
    -v "/tmp/renovatebot:/tmp/renovatebot" \
    -v "/srv/docker/joomla-renovatebot/config.js:/usr/src/app/config.js" \
    renovate/renovate \
    --base-dir=/tmp/renovatebot \
    --persist-repo-data=true \
    --binary-source=docker

module.exports = {
  platform: 'github',
  onboardingConfig: {
    extends: ['config:base', ':preserveSemverRanges', ':disableMajorUpdates'],
    versioning: 'semver',
    dependencyDashboard: true,
    lockFileMaintenance: { enabled: true },
    composerIgnorePlatformReqs: ["ext-*", "lib-*"],
    rangeStrategy: "update-lockfile"
  },
  enabledManagers: ['composer', 'npm'],
  forkMode: true,
  includeForks: true,
  repositories: [
    'joomla/joomla-cms'
  ],
  "allowedPostUpgradeCommands": ["^composer install", "^node build/build\.js --copy-assets$", "^npm run ", "^npm i$"],
};
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:base",
    ":preserveSemverRanges",
    ":disableMajorUpdates"
  ],
  "versioning": "semver",
  "dependencyDashboard": true,
  "lockFileMaintenance": { "enabled": true },
  "composerIgnorePlatformReqs": ["ext-*", "lib-*"],
  "rangeStrategy": "update-lockfile",
  "baseBranches": ["4.2-dev", "4.3-dev", "5.0-dev"],
  "constraints": {
    "composer": "> 2.3",
    "npm": "> 8.0"
  },
  "postUpgradeTasks": {
    "commands": ["npm ci", "node build/build.js --copy-assets"],
    "fileFilters": ["**/*.*"],
    "executionMode": "branch"
  }
}

That is the whole configuration we have. In a test repo I added composer install --ignore-reqs to the postUpgradeTasks and that one works fine, but npm ci fails because it requires nodejs 16. You can see the build.js here: https://github.com/joomla/joomla-cms/blob/4.2-dev/build/build.js And our repo is here: https://github.com/joomla/joomla-cms/

rarkins commented 1 year ago

@viceice were you thinking to limit it to sidecar images + user configurable tool constraints?

I'm also wondering if we need just the tool name and can reuse config.constraints?

viceice commented 1 year ago

we probably should do our idea of have a single sidecar image per repo, so all tools should be ready when running post upgrade tasks.

rarkins commented 1 year ago

Even then the user may want an extra tool or custom version installed for post upgrade tasks

viceice commented 1 year ago

Even then the user may want an extra tool or custom version installed for post upgrade tasks

then there needs to be some explicit tools definitions on post upgrade tasks for those tools.

rarkins commented 1 year ago

In that case I think we can start with the simplest use case. What do you think of this?

viceice commented 1 year ago

sounds good

rarkins commented 1 year ago

So let's have a new field installTools as a subfield of postUpgradeTasks, like this:\

  "constraints": {
    "composer": "> 2.3",
    "npm": "> 8.0"
  },
  "postUpgradeTasks": {
    "commands": ["npm ci", "node build/build.js --copy-assets"],
    "fileFilters": ["**/*.*"],
    "executionMode": "branch",
    "installTools": ["npm"]
  }

The possible tools should come from our existing list of supported tools.

rarkins commented 1 year ago

Reproduction forked to https://github.com/renovate-reproductions/8111

lalten commented 5 days ago

I'm trying to work around https://github.com/renovatebot/renovate/issues/25557 by running bazel mod deps --lockfile_mode=update in postUpgradeTasks in a renovatebot/github-action. Currently the command fails with /bin/sh: 1: bazel: not found as Bazel isn't installed in the Renovate container used in the action. I do have a container that is set up with everything needed to run our Bazel environment, is there a way to have postUpgradeTasks use that today?