From c4de23772982d3d0cb810748c75da64429db85ad Mon Sep 17 00:00:00 2001 From: Philip Harrison Date: Tue, 20 Jul 2021 15:00:30 +0100 Subject: [PATCH] Add updater integration spec --- __tests__/fixtures/job-details/npm.json | 47 +++++++++++++++++++++++ __tests__/updater-integration.test.ts | 51 +++++++++++++++++++++++++ __tests__/updater.test.ts | 9 ++++- package-lock.json | 4 +- src/dependabot-api.ts | 20 +++++++++- src/updater.ts | 11 ++++-- 6 files changed, 134 insertions(+), 8 deletions(-) create mode 100644 __tests__/fixtures/job-details/npm.json create mode 100644 __tests__/updater-integration.test.ts diff --git a/__tests__/fixtures/job-details/npm.json b/__tests__/fixtures/job-details/npm.json new file mode 100644 index 0000000..4e8ac53 --- /dev/null +++ b/__tests__/fixtures/job-details/npm.json @@ -0,0 +1,47 @@ +{ + "data": { + "attributes": { + "allowed-updates": [ + { + "dependency-type": "direct", + "update-type": "all" + } + ], + "credentials-metadata": [ + { + "type": "git_source", + "host": "github.com" + } + ], + "dependencies": null, + "existing-pull-requests": [], + "ignore-conditions": [], + "lockfile-only": false, + "max-updater-run-time": 2700, + "package-manager": "npm_and_yarn", + "source": { + "provider": "github", + "repo": "dsp-testing/dependabot-all-updates-test", + "directory": "/", + "branch": null, + "api-endpoint": "https://api.github.com/", + "hostname": "github.com" + }, + "updating-a-pull-request": false, + "update-subdependencies": false, + "requirements-update-strategy": null, + "security-advisories": [], + "security-updates-only": false, + "vendor-dependencies": false, + "reject-external-code": false, + "experiments": {}, + "commit-message-options": { + "include-scope": null, + "prefix": null, + "prefix-development": null + } + }, + "id": "1001", + "type": "update-jobs" + } +} diff --git a/__tests__/updater-integration.test.ts b/__tests__/updater-integration.test.ts new file mode 100644 index 0000000..9bd3fbe --- /dev/null +++ b/__tests__/updater-integration.test.ts @@ -0,0 +1,51 @@ +import Docker from 'dockerode' +import fs from 'fs' +import path from 'path' +import {Updater} from '../src/updater' + +describe('Updater', () => { + const docker = new Docker() + const mockDependabotAPI: any = { + getJobDetails: jest.fn(), + getCredentials: jest.fn(), + params: { + jobID: 1, + jobToken: 'xxx', + credentialsToken: 'yyy', + dependabotAPI: 'http://localhost' + } + } + const updater = new Updater(docker, mockDependabotAPI) + + afterEach(() => { + docker.listContainers(function (err, containers) { + if (!containers) return + + containers.forEach(function (containerInfo) { + if (containerInfo.Image.includes('docker.pkg.github.com/dependabot/dependabot-updater')) { + console.log('removing'); + + docker.getContainer(containerInfo.Id).remove(); + } + }); + }); + }); + + jest.setTimeout(20000) + it('should fetch manifests', async () => { + mockDependabotAPI.getJobDetails.mockImplementation(() => { + return JSON.parse(fs.readFileSync(path.join(__dirname, "fixtures/job-details/npm.json")).toString()).data.attributes + }) + mockDependabotAPI.getCredentials.mockImplementation(() => { + return [{ + type: "git_source", + host: "github.com", + username: "x-access-token", + password: process.env.GITHUB_TOKEN, + }] + }) + + await updater.pullImage() + await updater.runUpdater() + }) +}) diff --git a/__tests__/updater.test.ts b/__tests__/updater.test.ts index b865444..5ba8e08 100644 --- a/__tests__/updater.test.ts +++ b/__tests__/updater.test.ts @@ -4,7 +4,14 @@ import {Updater} from '../src/updater' describe('Updater', () => { const docker = new Docker() const mockDependabotAPI: any = { - getJobDetails: jest.fn() + getJobDetails: jest.fn(), + getCredentials: jest.fn(), + params: { + jobID: 1, + jobToken: 'xxx', + credentialsToken: 'yyy', + dependabotAPI: 'http://localhost' + } } const updater = new Updater(docker, mockDependabotAPI) diff --git a/package-lock.json b/package-lock.json index 58093ba..6e1b9fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2615,8 +2615,7 @@ "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "optionator": "^0.8.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -4428,7 +4427,6 @@ "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", "graceful-fs": "^4.2.4", "jest-regex-util": "^27.0.6", "jest-serializer": "^27.0.6", diff --git a/src/dependabot-api.ts b/src/dependabot-api.ts index 42e2924..ac4bdf8 100644 --- a/src/dependabot-api.ts +++ b/src/dependabot-api.ts @@ -23,7 +23,13 @@ export type JobDetails = { 'package-manager': PackageManager } -export type Credential = {} +export type Credential = { + type: string + host: string + username?: string + password?: string + token?: string +} export class DependabotAPI { constructor( @@ -42,4 +48,16 @@ export class DependabotAPI { return res.data.data.attributes } + + async getCredentials(): Promise { + const detailsURL = `/update_jobs/${this.params.jobID}/credentials` + const res = await this.client.get(detailsURL, { + headers: {Authorization: this.params.credentialsToken} + }) + if (res.status !== 200) { + throw new Error(`Unexpected status code: ${res.status}`) + } + + return res.data.data.attributes.credentials + } } diff --git a/src/updater.ts b/src/updater.ts index 8f1a580..d97c5c6 100644 --- a/src/updater.ts +++ b/src/updater.ts @@ -56,7 +56,8 @@ export class Updater { async runUpdater(): Promise { try { const details = await this.dependabotAPI.getJobDetails() - const credentials: Credential[] = [] // TODO: fetch credentials from API + const credentials = await this.dependabotAPI.getCredentials() + const files = await this.runFileFetcher(details, credentials) await this.runFileUpdater(details, files) } catch (e) { @@ -104,9 +105,9 @@ export class Updater { `DEPENDABOT_JOB_TOKEN=${this.dependabotAPI.params.jobToken}`, `DEPENDABOT_JOB_PATH=${JOB_INPUT_PATH}/${JOB_INPUT_FILENAME}`, `DEPENDABOT_OUTPUT_PATH=${JOB_OUTPUT_PATH}`, - `DEPENDABOT_API_URL=${this.dependabotAPI}` + `DEPENDABOT_API_URL=${this.dependabotAPI.params.dependabotAPI}` ], - Cmd: ['bin/run', 'fetch_files'] + Cmd: ['bin/run', updaterCommand] }) core.info(`Created ${updaterCommand} container: ${container.id}`) @@ -134,6 +135,10 @@ export class Updater { container.modem.demuxStream(stream, process.stdout, process.stderr) await container.wait() + const jobOutput = await container.getArchive({ + path: JOB_OUTPUT_PATH + }) + console.log('jobOutput', jobOutput) } finally { await container.remove() core.info(`Cleaned up container ${container.id}`)