Skip to content

Commit

Permalink
Merge pull request decentraland#12 from NodeFactoryIo/mpetrunic/ci-cd
Browse files Browse the repository at this point in the history
CI/CD
  • Loading branch information
mpetrunic authored Feb 15, 2021
2 parents d3b50af + d4ee4ec commit a1a4e90
Show file tree
Hide file tree
Showing 10 changed files with 1,250 additions and 87 deletions.
77 changes: 77 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
module.exports = {
"root": true,
"env": {
"mocha": true,
"node": true,
"es6": true
},
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint",
"prettier",
"eslint-plugin-import"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {
"@typescript-eslint/no-require-imports": "error",
"@typescript-eslint/no-unused-vars": ["error", {
"varsIgnorePattern": "^_"
}],
"@typescript-eslint/explicit-function-return-type": ["error", {
"allowExpressions": true
}],
"@typescript-eslint/ban-ts-comment": "error",
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/explicit-module-boundary-types": "error",
"@typescript-eslint/no-use-before-define": "off",
"prefer-const": "error",
"no-consecutive-blank-lines": 0,
"no-console": "error",
"@typescript-eslint/naming-convention": ["error",
{selector: "default", format: ['camelCase']},
{
selector: [
"classProperty", "parameterProperty", "objectLiteralProperty",
"classMethod", "parameter"
],
format: ['camelCase'], leadingUnderscore: "allow"
},
//variable must be in camel or upper case
{selector: "variable", format: ["camelCase"], leadingUnderscore: "allow"},
{selector: "variable", modifiers: ["global"], format: ["PascalCase", "UPPER_CASE"]},
//classes and types must be in PascalCase
{selector: ["typeLike", "enum"], format: ['PascalCase']},
{selector: "enumMember", format: null},
{selector: "typeProperty", format: ['PascalCase', 'camelCase']},
//ignore rules on destructured params
{
selector: "variable",
modifiers: ["destructured"],
format: null
}
],
"import/order": [
"error",
{
"groups": ["builtin", "external", "parent", "internal", "sibling"],
"newlines-between": "always",
"alphabetize": {
order: 'asc'
}
},
]
},
"overrides": [
{
"files": ["**/test/**/*.ts"],
"rules": {
"no-console": "off",
}
},
]
}
96 changes: 96 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: Release

on:
push:
branches:
- 'master'

jobs:
tag:
name: Check and Tag
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Get latest tag
uses: actions-ecosystem/action-get-latest-tag@v1
with:
with_initial_version: false
id: get-latest-tag

- name: Create tag
id: tag
uses: butlerlogic/[email protected]
with:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
tag_prefix: "v"
outputs:
tag: ${{ steps.tag.outputs.tagname }}
previous_tag: ${{ steps.get-latest-tag.outputs.tag }}
version: ${{ steps.tag.outputs.version }}

release:
name: Publish
runs-on: ubuntu-latest
needs: tag
if: needs.tag.outputs.tag != ''
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Setup Nodejs
uses: actions/setup-node@v1
with:
node-version: "14"
registry-url: "https://registry.npmjs.org"

- name: Install
run: yarn install --frozen-lockfile

- name: Build
run: yarn run build

- name: Generate changelog
id: changelog
uses: heinrichreimer/[email protected]
with:
token: ${{ secrets.GH_TOKEN }}
issues: "false"
issuesWoLabels: "false"
pullRequests: "true"
prWoLabels: "true"
author: "true"
usernamesAsGithubLogins: "true"
compareLink: "true"
filterByMilestone: "false"
unreleased: "false"
sinceTag: "${{ needs.tag.outputs.previous_tag }}"
maxIssues: "0"
stripGeneratorNotice: "true"

- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ needs.tag.outputs.tag }}
body_path: "CHANGELOG.md"
release_name: Release ${{ needs.tag.outputs.tag }}

- name: Publish to npm registry
run: yarn publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}

#in case of failure
- name: Rollback on failure
if: failure()
uses: author/action-rollback@9ec72a6af74774e00343c6de3e946b0901c23013
with:
id: ${{ steps.create_release.outputs.id }}
tag: ${{ needs.tag.outputs.tag }}
delete_orphan_tag: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21 changes: 21 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: CI

on: [pull_request, push]

jobs:
checks:
name: Checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2-beta
with:
node-version: "14"
- name: Install
run: yarn install --frozen-lockfile
- name: Build
run: yarn run build
- name: Lint
run: yarn run lint
- name: Tests
run: xvfb-run --auto-servernum yarn run test
10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc -p tsconfig.build.json",
"prepublish": "yarn run build",
"lint": "eslint --color --ext .ts src/ test/",
"lint:fix": "yarn run lint --fix",
"test": "mocha"
},
"repository": {
Expand All @@ -34,8 +35,15 @@
"devDependencies": {
"@types/mocha": "^7.0.2",
"@types/puppeteer": "^5.4.3",
"@typescript-eslint/eslint-plugin": "^4.15.0",
"@typescript-eslint/parser": "^4.15.0",
"eslint": "^7.20.0",
"eslint-config-prettier": "^7.2.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-prettier": "^3.3.1",
"ganache-core": "^2.13.2",
"mocha": "7.2.0",
"prettier": "^2.2.1",
"puppeteer": "5.5.0",
"serve-handler": "5.0.8",
"solc": "0.5.2",
Expand Down
24 changes: 15 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as puppeteer from 'puppeteer';
import downloader from './metamaskDownloader';

const timeout = seconds => new Promise(resolve => setTimeout(resolve, seconds * 1000))
import downloader from './metamaskDownloader';

export type LaunchOptions = Parameters<typeof puppeteer["launch"]>[0] & {
metamaskVersion?: string
Expand Down Expand Up @@ -31,10 +30,11 @@ export type TransactionOptions = {
gasLimit: number
}

export async function launch(puppeteer, { args, ...rest }: LaunchOptions = {}): Promise<puppeteer.Browser> {
export async function launch(pupeteerLib: typeof puppeteer, { args, ...rest }: LaunchOptions = {}): Promise<puppeteer.Browser> {
// eslint-disable-next-line @typescript-eslint/naming-convention
const METAMASK_PATH = await downloader(rest.metamaskVersion);

return puppeteer.launch({
return pupeteerLib.launch({
headless: false,
args: [
`--disable-extensions-except=${METAMASK_PATH}`,
Expand Down Expand Up @@ -119,6 +119,7 @@ export async function getMetamask(
await accountSwitcher.click()
const addAccount = await metamaskPage.waitForSelector('.account-menu > div:nth-child(7)')
await addAccount.click()
// eslint-disable-next-line @typescript-eslint/naming-convention
const PKInput = await metamaskPage.waitForSelector('input#private-key-box')
await PKInput.type(pk)
const importButton = await metamaskPage.waitForSelector('button.btn-secondary')
Expand Down Expand Up @@ -230,31 +231,36 @@ async function closeHomeScreen(browser: puppeteer.Browser): Promise<puppeteer.Pa
})
}

async function closeNotificationPage(browser: puppeteer.Browser) {
async function closeNotificationPage(browser: puppeteer.Browser): Promise<void> {
browser.on('targetcreated', async target => {
if (target.url() === 'chrome-extension://plkiloelkgnphnmaonlbbjbiphdalblo/notification.html') {
try {
const page = await target.page()
await page.close()
} catch {}
} catch {
return;
}
}
})
}

async function getMetamaskPage(browser, extensionId, extensionUrl) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async function getMetamaskPage(browser, extensionId, extensionUrl): Promise<void> {
// eslint-disable-next-line @typescript-eslint/naming-convention
const EXTENSION_ID = extensionId || 'nkbihfbeogaeaoehlefnkodbefgpgknn'
// eslint-disable-next-line @typescript-eslint/naming-convention
const EXTENSION_URL = extensionUrl || `chrome-extension://${EXTENSION_ID}/popup.html`

const metamaskPage = await browser.newPage()
await metamaskPage.goto(EXTENSION_URL)
}

async function confirmWelcomeScreen(metamaskPage: puppeteer.Page) {
async function confirmWelcomeScreen(metamaskPage: puppeteer.Page): Promise<void> {
const continueButton = await metamaskPage.waitForSelector('.welcome-page button')
await continueButton.click()
}

async function importAccount(metamaskPage: puppeteer.Page, seed: string, password: string) {
async function importAccount(metamaskPage: puppeteer.Page, seed: string, password: string): Promise<void> {
const importLink = await metamaskPage.waitForSelector('.first-time-flow button')
await importLink.click()

Expand Down
22 changes: 14 additions & 8 deletions src/metamaskDownloader.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import * as path from "path";
import * as fs from "fs";
import StreamZip from "node-stream-zip";
import {get} from "https";
import {IncomingMessage} from "http";
import {get} from "https";
import * as path from "path";

import StreamZip from "node-stream-zip";


const metamaskDirectory = path.resolve(__dirname, "metamask");
const MetamaskDirectory = path.resolve(__dirname, "metamask");

export default async (version?: string): Promise<string> => {
const {filename, downloadUrl, tag} = await getMetamaskReleases(version);
const extractDestination = path.resolve(metamaskDirectory, tag.replace(/\./g, "_"));
const extractDestination = path.resolve(MetamaskDirectory, tag.replace(/\./g, "_"));
if (!fs.existsSync(extractDestination)) {
const downloadedFile = await downloadMetamaskReleases(filename, downloadUrl);
const zip = new StreamZip.async({ file: downloadedFile });
Expand All @@ -18,6 +20,7 @@ export default async (version?: string): Promise<string> => {
return extractDestination;
}

// eslint-disable-next-line @typescript-eslint/naming-convention
const request = (url: string): Promise<IncomingMessage> => new Promise((resolve) => {
get(url, (response) => {
if(response.statusCode == 302) {
Expand All @@ -28,8 +31,9 @@ const request = (url: string): Promise<IncomingMessage> => new Promise((resolve)
});
});

// eslint-disable-next-line no-async-promise-executor, @typescript-eslint/naming-convention
const downloadMetamaskReleases = (name: string, url: string): Promise<string> => new Promise(async (resolve) => {
const downloadsDirectory = path.resolve(metamaskDirectory, "download");
const downloadsDirectory = path.resolve(MetamaskDirectory, "download");
if (!fs.existsSync(downloadsDirectory)) {
fs.mkdirSync(downloadsDirectory, { recursive: true });
}
Expand All @@ -41,9 +45,11 @@ const downloadMetamaskReleases = (name: string, url: string): Promise<string> =>
});

type MetamaskReleases = {downloadUrl: string, filename: string, tag: string};
const metamaskReleasesUrl = 'https://api.github.com/repos/metamask/metamask-extension/releases';
const MetamaskReleasesUrl = 'https://api.github.com/repos/metamask/metamask-extension/releases';
// eslint-disable-next-line @typescript-eslint/naming-convention
const getMetamaskReleases = (version?: string): Promise<MetamaskReleases> => new Promise((resolve, reject) => {
get(metamaskReleasesUrl, {headers: { 'User-Agent': 'Mozilla/5.0' }},(response) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
get(MetamaskReleasesUrl, {headers: { 'User-Agent': 'Mozilla/5.0' }},(response) => {
let body = "";
response.on("data", (chunk) => {
body += chunk;
Expand Down
8 changes: 5 additions & 3 deletions test/contract/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as path from 'path';
import * as fs from "fs";
import * as path from 'path';

import * as solc from "solc";

type ContractSources = Record<string, {content: string}>;
Expand All @@ -21,7 +22,7 @@ function buildSources():ContractSources {
return sources;
}

const input = {
const INPUT = {
language: 'Solidity',
sources: buildSources(),
settings: {
Expand All @@ -33,6 +34,7 @@ const input = {
}
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function compileContracts(): any {
return JSON.parse(solc.compile(JSON.stringify(input))).contracts;
return JSON.parse(solc.compile(JSON.stringify(INPUT))).contracts;
}
Loading

0 comments on commit a1a4e90

Please sign in to comment.