Skip to content

Commit

Permalink
Merge pull request #65 from snyk/develop
Browse files Browse the repository at this point in the history
Merge dev into master for release
  • Loading branch information
maxjeffos authored Jul 24, 2020
2 parents afb6017 + 8f91b4a commit 39c3c37
Show file tree
Hide file tree
Showing 21 changed files with 636 additions and 111 deletions.
84 changes: 82 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,93 @@ jobs:
steps:
- checkout
- run:
name: Test
name: Build
command: |
./scripts/ci-build.sh
npm test
- run:
name: Checks
command: |
npm run test:checks
- run:
name: Unit Tests
command: |
npm run test:unit
- run:
name: System Tests
command: |
npm run test:system
deploy_dev:
docker:
- image: circleci/node:lts
environment:
DEV_AZ_EXTENSION_ID: "dev-security-scan-test"
DEV_AZ_EXTENSION_NAME: "Dev - Snyk Security Scan"
DEV_AZ_TASK_FRIENDLY_NAME: "Dev - Snyk Security Scan"
DEV_AZ_TASK_NAME: "DevSnykSecurityScan"

working_directory: ~/repo
steps:
- checkout

- run:
name: Build Ops Sub-project
command: |
npm install
npm run deploy:format:check
npm run deploy:compile
- run:
name: Build and Deploy to Test Environment
command: |
echo DEV_AZ_ORG: $DEV_AZ_ORG # Set in CCI Project Settings
echo DEV_AZ_PUBLISHER: $DEV_AZ_PUBLISHER # Set in CCI Project Settings
echo DEV_AZ_EXTENSION_ID: $DEV_AZ_EXTENSION_ID
echo DEV_AZ_EXTENSION_NAME: $DEV_AZ_EXTENSION_NAME
echo DEV_AZ_TASK_FRIENDLY_NAME: $DEV_AZ_TASK_FRIENDLY_NAME
echo DEV_AZ_TASK_NAME: $DEV_AZ_TASK_NAME
npm run deploy:compile
NEXT_DEV_VERSION=$(node ./ops/deploy/dist/get-next-dev-ext-version.js)
if [[ $? -eq 0 ]]; then
echo NEXT_DEV_VERSION: $NEXT_DEV_VERSION
else
echo "no current version. Setting NEXT_DEV_VERSION to 0.0.1"
NEXT_DEV_VERSION=0.0.1
fi
echo "Deploying to dev with ${NEXT_DEV_VERSION} ${AZ_ORG}"
scripts/ci-deploy.sh $NEXT_DEV_VERSION $DEV_AZ_ORG
- run:
name: Launch Test Pipelines
command: |
node ./ops/deploy/dist/run-test-pipelines.js
deploy:
docker:
- image: circleci/node:lts
environment:
AZ_EXTENSION_ID: "snyk-security-scan"
AZ_EXTENSION_NAME: "Snyk Security Scan"
AZ_PUBLISHER: "Snyk"

working_directory: ~/repo
steps:
- checkout
- run:
name: Setup Env Vars
command: |
export AZURE_DEVOPS_EXT_PAT=$PROD_AZURE_DEVOPS_EXT_PAT
echo AZ_EXTENSION_ID: $AZ_EXTENSION_ID
echo AZ_EXTENSION_NAME: $AZ_EXTENSION_NAME
echo AZ_PUBLISHER: $AZ_PUBLISHER
- run:
name: Build and Deploy
command: |
export AZURE_DEVOPS_EXT_PAT=$PROD_AZURE_DEVOPS_EXT_PAT
npm install
npx semantic-release
Expand All @@ -29,6 +103,12 @@ workflows:
build_and_test:
jobs:
- test
- deploy_dev:
requires:
- test
filters:
branches:
ignore: master
- deploy:
context: nodejs-lib-release
requires:
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,5 @@ package-lock.json
*.bak
*.vsix
.eslintcache
.circleci
.ops
ops/deploy/dist
3 changes: 2 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
},
"testPathIgnorePatterns": [
"/node_modules/",
"snykTask/src/__tests__/_test-mock-config-*"
"snykTask/src/__tests__/_test-mock-config-*",
"snykTask/src/__tests__/test-task.ts"
]
}
15 changes: 15 additions & 0 deletions jest.config.system.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
"roots": [
"<rootDir>/snykTask/src/"
],
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"testPathIgnorePatterns": [
"/node_modules/",
"snykTask/src/__tests__/_test-mock-config-*"
],
testMatch: [
'<rootDir>/snykTask/src/__tests__/test-task.ts'
],
}
21 changes: 12 additions & 9 deletions ops/deploy/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
const fs = require("fs");
const path = require("path");
import * as myAz from "./azure-devops";
import * as ExtensionManagementInterfaces from "azure-devops-node-api/interfaces/ExtensionManagementInterfaces";
import { ChildProcess, exec, ExecException } from "child_process";

import {
installExtension,
uninstallExtension
} from "./lib/azure-devops/extensions";

import {
Command,
DeployTarget,
InputArgs,
parseInputParameters
} from "./cli-args";
import { ChildProcess, exec, ExecException } from "child_process";
import { getWebApi } from "./lib/azure-devops";

function checkVersionsMatch(): boolean {
const packageJsonFilePath = "package.json";
Expand Down Expand Up @@ -342,12 +346,12 @@ export async function updateOrInstallExtension(
}

const azUrl = getAzUrl(publishArgs.azureOrg);
const webApi = await getWebApi(azUrl, publishArgs.azureDevopsPAT);

// uninstall previous - this should be an option
// TODO: add an option like --install-new-version which, when set, will control whether we call uninstallPreviousVersion() / installNewVersion
await myAz.uninstallExtension(
azUrl,
publishArgs.azureDevopsPAT,
await uninstallExtension(
webApi,
publishArgs.vsMarketplacePublisher,
publishArgs.extensionId
);
Expand All @@ -362,9 +366,8 @@ export async function updateOrInstallExtension(
);

// install new version - this should be an option
await myAz.installExtension(
azUrl,
publishArgs.azureDevopsPAT,
await installExtension(
webApi,
publishArgs.vsMarketplacePublisher,
publishArgs.extensionId
);
Expand Down
31 changes: 31 additions & 0 deletions ops/deploy/get-current-dev-ext-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { getExtensionInfo, getLatestVersion } from "./lib/azure-devops";

async function main() {
const publisherName = process.env.DEV_AZ_PUBLISHER || "";
// warning: the Marketplace stuff calls this extensionId - the rest of the extension stuff calls it name
const extensionName = process.env.DEV_AZ_EXTENSION_ID || "";
const azToken = process.env.DEV_AZURE_DEVOPS_EXT_PAT || "";

const extensionDetails = await getExtensionInfo(
azToken,
publisherName,
extensionName
);

if (extensionDetails) {
const latestVersion = getLatestVersion(extensionDetails);
if (latestVersion) {
console.log(latestVersion);
} else {
console.error("could not get extension version info");
process.exit(1);
}
} else {
console.error("could not get extension info");
process.exit(1);
}
}

if (require.main === module) {
main();
}
36 changes: 36 additions & 0 deletions ops/deploy/get-next-dev-ext-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { getExtensionInfo, getLatestVersion } from "./lib/azure-devops";

async function main() {
const publisherName = process.env.DEV_AZ_PUBLISHER || "";
// warning: the Marketplace stuff calls this extensionId - the rest of the extension stuff calls it name
const extensionName = process.env.DEV_AZ_EXTENSION_ID || "";
const azToken = process.env.DEV_AZURE_DEVOPS_EXT_PAT || "";

const extensionDetails = await getExtensionInfo(
azToken,
publisherName,
extensionName
);

if (extensionDetails) {
const latestVersion = getLatestVersion(extensionDetails);
if (latestVersion) {
const splitz = latestVersion.split(".");
const major = parseInt(splitz[0]);
const minor = parseInt(splitz[1]);
const patch = parseInt(splitz[2]) + 1;
const newVersion = `${major}.${minor}.${patch}`;
console.log(newVersion);
} else {
console.error("could not get extension version info");
process.exit(1);
}
} else {
console.error("could not get extension info");
process.exit(1);
}
}

if (require.main === module) {
main();
}
54 changes: 54 additions & 0 deletions ops/deploy/install-extension-to-dev-org.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { WebApi } from "azure-devops-node-api";

import { getAzUrl, getWebApi } from "./lib/azure-devops";
import {
installExtension,
getInstalledExtensionInfo
} from "./lib/azure-devops/extensions";

async function main() {
const publisherName = process.env.DEV_AZ_PUBLISHER || "";
// warning: the Marketplace stuff calls this extensionId - the rest of the extension stuff calls it name
const extensionName = process.env.DEV_AZ_EXTENSION_ID || "";
const azToken = process.env.DEV_AZURE_DEVOPS_EXT_PAT || "";
const azOrg = process.env.DEV_AZ_ORG || "";

const azUrl = getAzUrl(azOrg);
const webApi: WebApi = await getWebApi(azUrl, azToken);

try {
const alreadyInstalledExtensionInfo = await getInstalledExtensionInfo(
webApi,
publisherName,
extensionName
);
const alreadyInstalledVersion = alreadyInstalledExtensionInfo.version;
console.log(
`Extension version currently installed: ${alreadyInstalledVersion}`
);

console.log(
"Attempting to install latest version of extension into org..."
);
// installExtension will throw an error if it is already installed
const installRes = await installExtension(
webApi,
publisherName,
extensionName
);

const afterInstallExtensionInfo = await getInstalledExtensionInfo(
webApi,
publisherName,
extensionName
);
const afterInstallExtensionVersion = afterInstallExtensionInfo.version;
console.log(`Extension version installed: ${afterInstallExtensionVersion}`);
} catch (err) {
console.log(`${err.statusCode} - ${err.message}`);
}
}

if (require.main === module) {
main();
}
74 changes: 74 additions & 0 deletions ops/deploy/lib/azure-devops/builds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import * as nodeApi from "azure-devops-node-api";
import * as BuildInterfaces from "azure-devops-node-api/interfaces/BuildInterfaces";

export async function getBuildDefinitions(
webApi: nodeApi.WebApi,
projectName: string
) {
const buildApi = await webApi.getBuildApi();
const buildDefinitions = await buildApi.getDefinitions(projectName);
return buildDefinitions;
}

export async function getBuildDefinition(
webApi: nodeApi.WebApi,
projectName: string,
buildDefinitionId: number
) {
const buildApi = await webApi.getBuildApi();
const buildDefinition = await buildApi.getDefinition(
projectName,
buildDefinitionId
);
return buildDefinition;
}

export async function getBuilds(
webApi: nodeApi.WebApi,
projectName: string,
buildDefinitionId
) {
const buildApi = await webApi.getBuildApi();
const buildDefinition = await buildApi.getBuilds(projectName, [
buildDefinitionId
]);
return buildDefinition;
}

export async function getBuild(
webApi: nodeApi.WebApi,
projectName: string,
buildId: number
) {
const buildApi = await webApi.getBuildApi();
const buildDefinition = await buildApi.getBuild(projectName, buildId);
return buildDefinition;
}

export async function queueBuild(
webApi: nodeApi.WebApi,
projectName: string,
build: BuildInterfaces.Build
) {
const buildApi = await webApi.getBuildApi();
const queueBuildResult: BuildInterfaces.Build = await buildApi.queueBuild(
build,
projectName
);
return queueBuildResult;
}

export async function launchBuildPipeline(
webApi: nodeApi.WebApi,
azOrg: string,
projectName: string,
buildDefinitionId: number
) {
const apiUrl = `https://dev.azure.com/${azOrg}/${projectName}/_apis/build/builds?api-version=5.1`;
const res = await webApi.rest.create(apiUrl, {
definition: {
id: buildDefinitionId
}
});
return res as any;
}
Loading

0 comments on commit 39c3c37

Please sign in to comment.