From 2a7612173897ff8f3f64ab5e91f24bc90fac0acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Cabessa?= Date: Fri, 21 Jul 2023 16:40:01 +0200 Subject: [PATCH] feat: allow to override docker command and user Add an option to specify a docker command and a docker user. It is useful if you need to customize your image before running `renovate`. It maybe a partial option for https://github.com/renovatebot/renovate/issues/8804 The idea start from this discussion https://github.com/renovatebot/renovate/discussions/23500 --- README.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ action.yml | 9 +++++++++ src/input.ts | 9 +++++++++ src/renovate.ts | 19 +++++++++++++++++++ 4 files changed, 84 insertions(+) diff --git a/README.md b/README.md index d8231b0f225..f984f4ff14d 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ GitHub Action to run Renovate self-hosted. - [`token`](#token) - [`renovate-image`](#renovate-image) - [`renovate-version`](#renovate-version) + - [`docker-cmd-file`](#docker-cmd-file) + - [`docker-user`](#docker-user) - [Example](#example) - [Environment Variables](#environment-variables) - [Passing other environment variables](#passing-other-environment-variables) @@ -172,6 +174,51 @@ jobs: We recommend you pin the version of Renovate to a full version or a full checksum, and use Renovate's regex manager to create PRs to update the pinned version. See `.github/workflows/build.yml` for an example of how to do this. +### `docker-cmd-file` + +Specify a command to run when the image start. By default the image run +`renovate` + +This option is useful to customize the image before running `renovate` + +For example you can create a simple script like this one (let's call it +`renovate-entrypoint.sh`) + +```sh +#!/bin/bash + +apt update + +apt install -y build-essential libpq-dev + +runuser -u ubuntu renovate +``` + +Now use this action + +```yml +.... +jobs: + renovate: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3.5.3 + - name: Self-hosted Renovate + uses: renovatebot/github-action@v39.0.0 + with: + docker-cmd-file: .github/renovate-entrypoint.sh + docker-user: root + token: ${{ secrets.RENOVATE_TOKEN }} +``` + +### `docker-user` + +Specify a user (or user-id) to run docker command. + +You can use it with [`docker-cmd-file`](#docker-cmd-file) in order to start the +image as root, do some customization and switch back to a unprivileged user. + ## Example This example uses a Personal Access Token and will run every 15 minutes. diff --git a/action.yml b/action.yml index 325990a578b..4306b0b566a 100644 --- a/action.yml +++ b/action.yml @@ -36,6 +36,15 @@ inputs: can use Docker. Also add the user inside the renovate container to the docker group for socket permissions. required: false + docker-cmd-file: + description: | + Override docker command. Default command is `renovate` + required: false + docker-user: + description: | + Docker user. Default to an unprivileged user + required: false + runs: using: node16 main: dist/index.js diff --git a/src/input.ts b/src/input.ts index f24a6301da5..c3e7ce4f099 100644 --- a/src/input.ts +++ b/src/input.ts @@ -73,6 +73,15 @@ class Input { return core.getInput('mount-docker-socket') === 'true'; } + getDockerCmdFile(): string | null { + const cmdFile = core.getInput('docker-cmd-file'); + return !!cmdFile && cmdFile !== '' ? path.resolve(cmdFile) : null; + } + + getDockerUser(): string | null { + return core.getInput('docker-user') || null; + } + /** * Convert to environment variables. * diff --git a/src/renovate.ts b/src/renovate.ts index 9677c85043a..33f06ca7feb 100644 --- a/src/renovate.ts +++ b/src/renovate.ts @@ -7,6 +7,7 @@ import path from 'path'; class Renovate { static dockerGroupRegex = /^docker:x:(?[1-9][0-9]*):/m; private configFileMountDir = '/github-action'; + private entrypointMountDir = '/'; private docker: Docker; @@ -39,8 +40,26 @@ class Renovate { ); } + const docker_cmd_file = this.input.getDockerCmdFile(); + let docker_cmd = null; + if (docker_cmd_file !== null) { + const baseName = path.basename(docker_cmd_file); + const mountPath = path.join(this.entrypointMountDir, baseName); + dockerArguments.push(`--volume ${docker_cmd_file}:${mountPath}`); + docker_cmd = mountPath; + } + + const docker_user = this.input.getDockerUser(); + if (docker_user !== null) { + dockerArguments.push(`--user ${docker_user}`); + } + dockerArguments.push('--volume /tmp:/tmp', '--rm', this.docker.image()); + if (docker_cmd !== null) { + dockerArguments.push(docker_cmd); + } + const command = `docker run ${dockerArguments.join(' ')}`; const code = await exec(command);