Add Jenkins Integration (#1295)
* add jenkins changes * run prettier * update icons * update icons to use latest favicon
This commit is contained in:
parent
9be46bf8aa
commit
937cc3fde5
Binary file not shown.
Before Width: | Height: | Size: 788 KiB After Width: | Height: | Size: 15 KiB |
Binary file not shown.
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,6 @@
|
|||
FROM electronuserland/builder:wine-03.18
|
||||
|
||||
RUN mkdir /hostHome
|
||||
RUN apt-get update && apt-get install -y libusb-1.0 nasm graphicsmagick autoconf automake libtool python-pip
|
||||
RUN pip install awscli --upgrade --user
|
||||
ENV PATH "$PATH:/root/.local/bin"
|
|
@ -0,0 +1,26 @@
|
|||
pipeline {
|
||||
agent {
|
||||
dockerfile {
|
||||
filename 'Dockerfile'
|
||||
dir 'jenkins/Docker'
|
||||
args '--env ETH_SIGNING_KEY=$ETH_SIGNING_KEY --env S3_BUCKET_NAME=$S3_BUCKET_NAME'
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage('Build') {
|
||||
environment {
|
||||
ELECTRON_BUILDER_ALLOW_UNRESOLVED_DEPENDENCIES = 1
|
||||
}
|
||||
steps {
|
||||
sh 'rm -rf node_modules'
|
||||
sh 'npm install'
|
||||
sh 'npm run jenkins:build:linux'
|
||||
}
|
||||
}
|
||||
stage('Upload') {
|
||||
steps {
|
||||
sh 'npm run jenkins:upload'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
const VERSION = require('../package.json').version;
|
||||
const GIT_COMMIT = process.env.GIT_COMMIT || 'commit-not-set';
|
||||
const GIT_COMMIT_SHORT = GIT_COMMIT.substring(0, 7);
|
||||
const JENKINS_BUILD_ID = process.env.BUILD_ID;
|
||||
const LINUX_FILES = [`MyCrypto-${VERSION}-i386.AppImage`, `MyCrypto-${VERSION}-x86_64.AppImage`];
|
||||
const WINDOWS_FILES = [`MyCrypto Setup ${VERSION}.exe`, `MyCrypto Setup ${VERSION}.exe.blockmap`];
|
||||
const OSX_FILES = [];
|
||||
const FLAVOR = (() => {
|
||||
const { platform } = process;
|
||||
|
||||
if (platform === 'linux') {
|
||||
return 'linux-windows';
|
||||
} else if (platform === 'darwin') {
|
||||
return 'mac';
|
||||
} else {
|
||||
throw new Error('Unsupported platform.');
|
||||
}
|
||||
})();
|
||||
const S3_BUCKET = process.env.S3_BUCKET_NAME;
|
||||
const ETH_SIGNING_KEY = process.env.ETH_SIGNING_KEY;
|
||||
|
||||
module.exports = {
|
||||
VERSION,
|
||||
GIT_COMMIT,
|
||||
GIT_COMMIT_SHORT,
|
||||
JENKINS_BUILD_ID,
|
||||
LINUX_FILES,
|
||||
WINDOWS_FILES,
|
||||
OSX_FILES,
|
||||
FLAVOR,
|
||||
S3_BUCKET,
|
||||
ETH_SIGNING_KEY
|
||||
};
|
|
@ -0,0 +1,112 @@
|
|||
const path = require('path');
|
||||
const { createHash } = require('crypto');
|
||||
const { readFileSync } = require('fs');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
const { hashPersonalMessage, ecsign, toBuffer, addHexPrefix } = require('ethereumjs-util');
|
||||
|
||||
const genCommitFilename = (name, version, commit, buildId) => {
|
||||
const split = name.split(version);
|
||||
return `${split[0]}${version}-${commit}-${buildId}${split[1]}`;
|
||||
};
|
||||
|
||||
const genFileList = (linux, windows, osx) => {
|
||||
const { platform } = process;
|
||||
if (platform === 'linux') {
|
||||
return [...linux, ...windows];
|
||||
} else if (platform === 'darwin') {
|
||||
return [...osx];
|
||||
} else {
|
||||
throw new Error('Unrecognized host platform.');
|
||||
}
|
||||
};
|
||||
|
||||
const genSha512 = filePath => {
|
||||
const hash = createHash('sha512');
|
||||
const data = readFileSync(filePath);
|
||||
hash.update(data);
|
||||
return hash.digest('hex');
|
||||
};
|
||||
|
||||
const runChildProcess = cmd =>
|
||||
new Promise((resolve, reject) => {
|
||||
const child = spawn('sh', ['-c', cmd]);
|
||||
|
||||
child.stdout.on('data', data => {
|
||||
process.stdout.write(data);
|
||||
});
|
||||
|
||||
child.stderr.on('data', data => {
|
||||
process.stderr.write(data);
|
||||
});
|
||||
|
||||
child.on('close', code => {
|
||||
if (code !== 0) {
|
||||
return reject(`Child process exited with code: ${code}`);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
const uploadToS3 = (localFilePath, s3FilePath) =>
|
||||
runChildProcess(`aws s3 cp "${localFilePath}" "${s3FilePath}"`);
|
||||
|
||||
const genS3Url = (filename, commit, bucket) => `s3://${bucket}/${commit}/${filename}`;
|
||||
|
||||
const genManifestFile = manifest =>
|
||||
manifest.map(info => ({
|
||||
Filename: info.commitFilename,
|
||||
SHA512: info.fileHash
|
||||
}));
|
||||
|
||||
const genManifestFilename = (flavor, version, commit, buildId) =>
|
||||
`manifest.${flavor}.v${version}.${commit}.${buildId}.json`;
|
||||
|
||||
const genSignatureFile = (manifestHash, pKeyString) => {
|
||||
const pKeyBuffer = Buffer.from(pKeyString, 'hex');
|
||||
return signMessageWithPrivKeyV2(pKeyBuffer, manifestHash);
|
||||
};
|
||||
|
||||
const genSignatureFilename = (flavor, version, commit, buildId) =>
|
||||
`manifest.${flavor}.v${version}.${commit}.${buildId}.signature`;
|
||||
|
||||
const genManifest = (fileList, version, jenkinsBuildId, gitCommit, gitCommitShort, s3Bucket) =>
|
||||
fileList.map(filename => {
|
||||
const fullPath = path.resolve('dist/electron-builds/', filename);
|
||||
const commitFilename = genCommitFilename(filename, version, gitCommitShort, jenkinsBuildId);
|
||||
|
||||
return {
|
||||
fullPath,
|
||||
filename,
|
||||
commitFilename,
|
||||
fileHash: genSha512(fullPath),
|
||||
s3Url: genS3Url(commitFilename, gitCommit, s3Bucket)
|
||||
};
|
||||
});
|
||||
|
||||
function signMessageWithPrivKeyV2(privKey, msg) {
|
||||
const hash = hashPersonalMessage(toBuffer(msg));
|
||||
const signed = ecsign(hash, privKey);
|
||||
const combined = Buffer.concat([
|
||||
Buffer.from(signed.r),
|
||||
Buffer.from(signed.s),
|
||||
Buffer.from([signed.v])
|
||||
]);
|
||||
const combinedHex = combined.toString('hex');
|
||||
|
||||
return addHexPrefix(combinedHex);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
genCommitFilename,
|
||||
genManifestFile,
|
||||
genFileList,
|
||||
genSha512,
|
||||
genS3Url,
|
||||
uploadToS3,
|
||||
signMessageWithPrivKeyV2,
|
||||
genManifestFilename,
|
||||
genManifest,
|
||||
genSignatureFile,
|
||||
genSignatureFilename
|
||||
};
|
|
@ -0,0 +1,68 @@
|
|||
const path = require('path');
|
||||
const { writeFileSync } = require('fs');
|
||||
|
||||
const {
|
||||
VERSION,
|
||||
FLAVOR,
|
||||
GIT_COMMIT,
|
||||
GIT_COMMIT_SHORT,
|
||||
LINUX_FILES,
|
||||
WINDOWS_FILES,
|
||||
OSX_FILES,
|
||||
S3_BUCKET,
|
||||
JENKINS_BUILD_ID,
|
||||
ETH_SIGNING_KEY
|
||||
} = require('./constants');
|
||||
|
||||
const {
|
||||
genSha512,
|
||||
genFileList,
|
||||
genCommitFilename,
|
||||
genS3Url,
|
||||
genManifest,
|
||||
genManifestFile,
|
||||
genManifestFilename,
|
||||
genSignatureFile,
|
||||
genSignatureFilename,
|
||||
uploadToS3
|
||||
} = require('./lib');
|
||||
|
||||
const fileList = genFileList(WINDOWS_FILES, LINUX_FILES, OSX_FILES);
|
||||
|
||||
const manifest = genManifest(
|
||||
fileList,
|
||||
VERSION,
|
||||
JENKINS_BUILD_ID,
|
||||
GIT_COMMIT,
|
||||
GIT_COMMIT_SHORT,
|
||||
S3_BUCKET
|
||||
);
|
||||
|
||||
const manifestFile = genManifestFile(manifest);
|
||||
const manifestFilename = genManifestFilename(FLAVOR, VERSION, GIT_COMMIT_SHORT, JENKINS_BUILD_ID);
|
||||
const manifestFilePath = path.resolve(`./${manifestFilename}`);
|
||||
const manifestS3Url = genS3Url(manifestFilename, GIT_COMMIT, S3_BUCKET);
|
||||
|
||||
// write manifest file
|
||||
writeFileSync(manifestFilename, JSON.stringify(manifestFile, null, 2), 'utf8');
|
||||
|
||||
const manifestHash = genSha512(manifestFilePath);
|
||||
|
||||
const signatureFile = genSignatureFile(manifestHash, ETH_SIGNING_KEY);
|
||||
const signatureFilename = genSignatureFilename(FLAVOR, VERSION, GIT_COMMIT_SHORT, JENKINS_BUILD_ID);
|
||||
const signatureFilePath = path.resolve(`./${signatureFilename}`);
|
||||
const signatureS3Url = genS3Url(signatureFilename, GIT_COMMIT, S3_BUCKET);
|
||||
|
||||
// write signature file
|
||||
writeFileSync(signatureFilePath, signatureFile, 'utf8');
|
||||
|
||||
// upload all the things to S3
|
||||
(async () => {
|
||||
for (let fileInfo of manifest) {
|
||||
const { fullPath, s3Url } = fileInfo;
|
||||
await uploadToS3(fullPath, s3Url);
|
||||
}
|
||||
|
||||
await uploadToS3(manifestFilePath, manifestS3Url);
|
||||
await uploadToS3(signatureFilePath, signatureS3Url);
|
||||
})();
|
|
@ -152,6 +152,9 @@
|
|||
"build:electron:windows": "webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=windows node webpack_config/buildElectron.js",
|
||||
"build:electron:linux": "webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=linux node webpack_config/buildElectron.js",
|
||||
"prebuild:electron": "check-node-version --package",
|
||||
"jenkins:build:linux": "webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=JENKINS_LINUX node webpack_config/buildElectron.js",
|
||||
"jenkins:build:mac": "webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=JENKINS_MAC node webpack_config/buildElectron.js",
|
||||
"jenkins:upload": "node jenkins/upload",
|
||||
"test:coverage": "jest --config=jest_config/jest.config.json --coverage",
|
||||
"test": "jest --config=jest_config/jest.config.json",
|
||||
"test:unit": "jest --config=jest_config/jest.config.json --coverage",
|
||||
|
|
|
@ -6,7 +6,15 @@ const builder = require('electron-builder');
|
|||
const config = require('./config');
|
||||
|
||||
function shouldBuildOs(os) {
|
||||
return !process.env.ELECTRON_OS || process.env.ELECTRON_OS === os;
|
||||
const { ELECTRON_OS } = process.env;
|
||||
|
||||
if (ELECTRON_OS === 'JENKINS_LINUX') {
|
||||
return os === 'linux' || os === 'windows';
|
||||
} else if (ELECTRON_OS === 'JENKINS_MAC') {
|
||||
return os === 'mac';
|
||||
} else {
|
||||
return !process.env.ELECTRON_OS || process.env.ELECTRON_OS === os;
|
||||
}
|
||||
}
|
||||
|
||||
async function build() {
|
||||
|
@ -36,7 +44,7 @@ async function build() {
|
|||
productName: 'MyCrypto',
|
||||
directories: {
|
||||
app: jsBuildDir,
|
||||
output: electronBuildsDir,
|
||||
output: electronBuildsDir
|
||||
},
|
||||
mac: {
|
||||
category: 'public.app-category.finance',
|
||||
|
@ -49,14 +57,11 @@ async function build() {
|
|||
},
|
||||
linux: {
|
||||
category: 'Finance',
|
||||
icon: path.join(config.path.electron, 'icons/icon.png'),
|
||||
compression
|
||||
},
|
||||
publish: {
|
||||
provider: 'github',
|
||||
owner: 'MyCryptoHQ',
|
||||
repo: 'MyCrypto',
|
||||
vPrefixedTagName: false
|
||||
},
|
||||
// IMPORTANT: Prevents from auto publishing to GitHub in CI environments
|
||||
publish: null,
|
||||
// IMPORTANT: Prevents extending configs in node_modules
|
||||
extends: null
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue