diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f1f331c3..1b8fbf6a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,10 +55,14 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2.1.0 + - name: Install project + run: npm ci + - name: Build + run: npm run build - name: Renovate test uses: ./ with: - configurationFile: .github/config.js + configurationFile: example/renovate-config.js token: ${{ secrets.RENOVATE_TOKEN }} build: diff --git a/.github/workflows/example.yml b/.github/workflows/example.yml deleted file mode 100644 index 630ae56f..00000000 --- a/.github/workflows/example.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Example -on: - push: - branches: - - master - pull_request: -jobs: - example: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2.1.0 - - name: Renovate example - uses: ./ - with: - configurationFile: example/config.js - token: ${{ secrets.RENOVATE_TOKEN }} diff --git a/action.yml b/action.yml index a1cb6010..f48c435d 100644 --- a/action.yml +++ b/action.yml @@ -15,8 +15,5 @@ inputs: configured using a Secret. required: true runs: - using: docker - image: src/Dockerfile - args: - - ${{ inputs.configurationFile }} - - ${{ inputs.token }} + using: node12 + main: dist/index.js diff --git a/example/config.js b/example/config.js deleted file mode 100644 index e6b7683b..00000000 --- a/example/config.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - branchPrefix: 'ga-renovate/', - dryRun: true, - gitAuthor: 'Renovate Bot ', - logLevel: 'debug', - onboarding: false, - platform: 'github', - repositories: ['renovatebot/github-action'], -}; diff --git a/.github/config.js b/example/renovate-config.js similarity index 100% rename from .github/config.js rename to example/renovate-config.js diff --git a/package-lock.json b/package-lock.json index 9ce28f4f..af98a2ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,24 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@actions/core": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.4.tgz", + "integrity": "sha512-YJCEq8BE3CdN8+7HPZ/4DxJjk/OkZV2FFIf+DlZTC/4iBlzYCD5yjRR6eiOS5llO11zbRltIRuKAjMKaWTE6cg==" + }, + "@actions/exec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.0.4.tgz", + "integrity": "sha512-4DPChWow9yc9W3WqEbUj8Nr86xkpyE29ZzWjXucHItclLbEW6jr80Zx4nqv18QL6KK65+cifiQZXvnqgTV6oHw==", + "requires": { + "@actions/io": "^1.0.1" + } + }, + "@actions/io": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.2.tgz", + "integrity": "sha512-J8KuFqVPr3p6U8W93DOXlXW6zFvrQAJANdS+vw0YhusLIq+bszW8zmK2Fh1C2kDPX8FMvwIl1OUcFgvJoXLbAg==" + }, "@babel/code-frame": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", @@ -308,6 +326,12 @@ "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", "dev": true }, + "@types/node": { + "version": "13.13.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.4.tgz", + "integrity": "sha512-x26ur3dSXgv5AwKS0lNfbjpCakGIduWU1DU91Zz58ONRWrIKGunmZBNv4P7N+e27sJkiGDsw/3fT4AtsqQBrBA==", + "dev": true + }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", diff --git a/package.json b/package.json index 954889c5..217ef4f0 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "1.0.5", "description": "GitHub Action to run Renovate self-hosted.", "private": true, + "main": "dist/index.js", "scripts": { "lint": "concurrently npm:lint-es", "lint:fix": "concurrently npm:lint-es:fix", @@ -16,7 +17,8 @@ "release:changelog": "standard-version --dry-run --skip.commit=true --skip.tag=true", "release:commit": "git commit --allow-empty -m \"chore(release): trigger release process [ci release]\"", "release:message": "chalk -t \"Run {green.bold git push} to publish the release or {red.bold git reset HEAD^} to undo the release.\"", - "release": "run-s release:changelog release:commit release:message" + "release": "run-s release:changelog release:commit release:message", + "build": "tsc" }, "repository": { "type": "git", @@ -28,10 +30,14 @@ "url": "https://github.com/renovatebot/github-action/issues" }, "homepage": "https://github.com/renovatebot/github-action#readme", - "dependencies": {}, + "dependencies": { + "@actions/core": "1.2.4", + "@actions/exec": "1.0.4" + }, "devDependencies": { "@commitlint/cli": "8.3.5", "@commitlint/config-conventional": "8.3.4", + "@types/node": "13.13.4", "@typescript-eslint/eslint-plugin": "2.30.0", "@typescript-eslint/parser": "2.30.0", "chalk-cli": "4.1.0", diff --git a/src/Dockerfile b/src/Dockerfile deleted file mode 100644 index b52db8f7..00000000 --- a/src/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM renovate/renovate:19.228.2 - -COPY entrypoint.sh /usr/entrypoint.sh - -ENTRYPOINT ["/usr/entrypoint.sh"] diff --git a/src/docker.ts b/src/docker.ts new file mode 100644 index 00000000..9d0a0c2b --- /dev/null +++ b/src/docker.ts @@ -0,0 +1,15 @@ +class Docker { + readonly repository = 'renovate/renovate'; + // renovate: datasource=docker depName=renovate/renovate versioning=docker + readonly tag = '19.228.1'; + + image(): string { + return `${this.repository}:${this.tag}`; + } + + version(): string { + return this.tag; + } +} + +export default Docker; diff --git a/src/entrypoint.sh b/src/entrypoint.sh deleted file mode 100755 index 5c1dab49..00000000 --- a/src/entrypoint.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# -# Entrypoint for Docker. - -export RENOVATE_CONFIG_FILE="${GITHUB_WORKSPACE}/${1}" -readonly _RENOVATE_TOKEN="${2}" - -# We are running as ubuntu, so no write access to /github/home -export HOME=/home/ubuntu - -if [[ ! -f "${RENOVATE_CONFIG_FILE}" ]]; then - echo "ERROR: Couldn't find file ${RENOVATE_CONFIG_FILE}" 1>&2 - exit 1 -fi - -# Run Renovate. -# -# Mimic the original ENTRYPOINT of the renovate/renovate Docker container. See -# the following link for this entry. -# https://github.com/renovatebot/docker-renovate/blob/d3aa0d99931ea7ad7e901a1e538eba0d61268229/Dockerfile#L63 - -RENOVATE_TOKEN="${_RENOVATE_TOKEN}" /usr/local/bin/docker-entrypoint.sh diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 00000000..012c7f52 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,17 @@ +import * as core from '@actions/core'; +import Input from './input'; +import Renovate from './renovate'; + +async function run(): Promise { + try { + const input = new Input(); + const renovate = new Renovate(input.configurationFile, input.token); + + await renovate.runDockerContainer(); + } catch (error) { + console.error(error); + core.setFailed(error.message); + } +} + +run(); diff --git a/src/input.ts b/src/input.ts new file mode 100644 index 00000000..207a394c --- /dev/null +++ b/src/input.ts @@ -0,0 +1,20 @@ +import * as core from '@actions/core'; + +class Input { + readonly configurationFile = core.getInput('configurationFile', { + required: true, + }); + readonly token = core.getInput('token', { required: true }); + + constructor() { + this.validate(); + } + + validate(): void { + if (this.token === '') { + throw new Error('input.token MUST NOT be empty'); + } + } +} + +export default Input; diff --git a/src/renovate.ts b/src/renovate.ts new file mode 100644 index 00000000..c0048cb2 --- /dev/null +++ b/src/renovate.ts @@ -0,0 +1,55 @@ +import Docker from './docker'; +import { exec } from '@actions/exec'; +import fs from 'fs'; +import path from 'path'; + +class Renovate { + private configFileEnv = 'RENOVATE_CONFIG_FILE'; + private tokenEnv = 'RENOVATE_TOKEN'; + private configFileMountDir = '/github-action'; + + private configFile: string; + private docker: Docker; + + constructor(configFile: string, private token: string) { + this.configFile = path.resolve(configFile); + + this.validateArguments(); + + this.docker = new Docker(); + } + + async runDockerContainer(): Promise { + const commandArguments = [ + '--rm', + `--env ${this.configFileEnv}=${this.configFileMountPath()}`, + `--env ${this.tokenEnv}=${this.token}`, + `--volume ${this.configFile}:${this.configFileMountPath()}`, + this.docker.image(), + ]; + const command = `docker run ${commandArguments.join(' ')}`; + + const code = await exec(command); + if (code !== 0) { + new Error(`'docker run' failed with exit code ${code}.`); + } + } + + private validateArguments(): void { + if (!fs.existsSync(this.configFile)) { + throw new Error( + `Could not locate configuration file '${this.configFile}'.` + ); + } + } + + private configFileName(): string { + return path.basename(this.configFile); + } + + private configFileMountPath(): string { + return path.join(this.configFileMountDir, this.configFileName()); + } +} + +export default Renovate; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..7ed8f2e3 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "moduleResolution": "node", + "declaration": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "outDir": "dist" + }, + "include": ["src/**/*.ts", "bin/**/*.ts"], + "exclude": ["node_modules", "**/*.test.ts"] +}