feat(codesign): add codesign script

This commit is contained in:
George Lima 2019-04-09 23:39:47 -03:00
parent 5951301fe6
commit 5fdbc43bd1
4 changed files with 383 additions and 1 deletions

View File

@ -9,6 +9,7 @@
"start": "yarn check --integrity && concurrently \"cross-env BROWSER=none yarn dev\" \"wait-on http://0.0.0.0:8080 && yarn electron:dev\"",
"dev": "webpack-dev-server --config config/webpack-dev.config.js --mode development --open --hot",
"build": "rm -rf build && webpack --config config/webpack-prod.config.js --mode production --env.NODE_ENV=production",
"release": "node -r @babel/register ./scripts/release.js",
"lint:precommit": "eslint ./app/",
"flow:precommit": "glow",
"flow:coverage": "flow-coverage-report --config ./coverage.json",
@ -47,6 +48,7 @@
"@babel/preset-env": "^7.0.0",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@octokit/rest": "^16.23.4",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.4",
"concurrently": "^4.1.0",
@ -78,6 +80,7 @@
"jest": "^24.5.0",
"jest-dom": "^2.1.1",
"jest-extended": "^0.11.0",
"mime-types": "^2.1.22",
"node-sass": "^4.8.3",
"postcss-loader": "^3.0.0",
"pre-commit": "^1.2.2",

188
scripts/codesign.sh Executable file
View File

@ -0,0 +1,188 @@
#!/bin/bash
# Setup
bold=$(tput bold)
normal=$(tput sgr0)
# Print the usage and exit
do_help() {
echo "codesign.sh v0.1";
echo "";
echo "Sign release binaries with gpg keysigning"
echo "";
echo "Usage:"
echo "Signing binaries:"
echo " Codesign a list of files"
echo " ${bold}codesign.sh file [file ...]${normal}";
echo ""
echo "Export Public Key:"
echo " Export the public key of the signing key"
echo " ${bold}codesign.sh --public${normal}"
echo ""
echo ""
echo "Upload Public Key:"
echo " Upload the public key to public keyservers, so users can discover them."
echo " ${bold}codesign.sh --upload${normal} --key KEY_FINGERPRINT"
exit 1;
}
# Print the instructions for how to install dependencies
do_missing_command() {
echo "Error: ${bold}$1${normal} was not installed"
echo ""
echo "One or more dependencies are missing. Please install all dependencies by running:"
if [[ "$OSTYPE" == "darwin"* ]]; then
echo "${bold}brew install gsha256sum gnupg${normal}"
else
echo "${bold}sudo apt install sha256sum gnupg${normal}"
fi
exit 1;
}
# No input files were specified
do_missing_arguments() {
echo "${bold}Error:${normal} No inputs files were specified"
echo
do_help
}
# Print error message for missing private key
do_missing_gpg_key() {
echo "Error: Couldn't find a local private key to sign with."
echo
echo "The command ${bold}gpg -K${normal} didn't return any keys. Did you forget to install the private keys on this machine?"
echo
echo "You can generate a new key by running ${bold}gpg --full-generate-key${normal}"
echo "Note: If you password protect your key, you'll need to enter the password interactively while signing files."
exit 1;
}
# Export the Public key in the ascii format
do_export_public_key() {
# Check to see that we have a private key installed on this machine
if [[ -z $(gpg -K) ]]; then
do_missing_gpg_key
fi
gpg --armour --export
exit 1;
}
# Upload the public key to public keyservers
do_upload_public_key() {
# Check to see that we have a private key installed on this machine
if [[ -z $(gpg -K) ]]; then
do_missing_gpg_key
fi
# Check to see if the finger print argument was specified
if [ -z $KEY_FINGERPRINT ]; then
echo "${bold}Error:${normal} no key was specified"
echo ""
echo "Upload keys with"
echo " codesign.sh --upload KEY_FINGERPRINT"
echo
echo "You can get the fingerprint of your keys by looking at the output of ${bold}gpg --check-sigs${normal}"
echo " The fingerprint is the first column in the lines begining with \"sig!\" or \"sig!3\""
echo
exit 1;
fi
echo "Uploading Public Key to Public Servers"
echo "This will take some time..."
echo
gpg --keyserver certserver.pgp.com --send-key $KEY_FINGERPRINT
gpg --keyserver pgp.mit.edu --send-key $KEY_FINGERPRINT
gpg --keyserver keyserver.ubuntu.com --send-key $KEY_FINGERPRINT
gpg --keyserver pool.sks-keyservers.net --send-key $KEY_FINGERPRINT
gpg --keyserver pgp.key-server.io --send-key $KEY_FINGERPRINT
gpg --keyserver keys.gnupg.net --send-key $KEY_FINGERPRINT
echo "All Done"
exit 1;
}
# Accept the variables as command line arguments as well
POSITIONAL=()
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-h|--help)
do_help
;;
-p|--public)
do_export_public_key
;;
-u|--upload)
KEY_FINGERPRINT="$2"
do_upload_public_key
;;
*) # unknown option
POSITIONAL+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters
# Check for argument list, to make sure there are some files specified
if [ $# -eq 0 ]; then
do_missing_arguments
fi
if [[ "$OSTYPE" == "darwin"* ]]; then
SHA256SUM=gsha256sum
else
SHA256SUM=sha256sum
fi
# Check for existance of the gpg and sha256sum commands
hash $SHA256SUM 2>/dev/null || {
do_missing_command $SHA256SUM
exit 1;
}
hash gpg 2>/dev/null || {
do_missing_command gpg
exit 1;
}
hash zip 2>/dev/null || {
do_missing_command zip
exit 1;
}
# Check to see that we have a private key installed on this machine
if [[ -z $(gpg -K) ]]; then
do_missing_gpg_key
fi
PackageContents=()
# Calculate the sha256sum for all input files
$SHA256SUM $@ > sha256sum.txt
PackageContents+=("sha256sum.txt")
# Sign all the files
for var in "$@"
do
rm -f $var.sig
echo "Signing" $var
gpg --batch --output $var.sig --detach-sig $var
PackageContents+=("$var.sig")
done
# Zip up everything into a neat package
ZipName=signatures.zip
echo "Zipping files into $ZipName"
rm -f $ZipName
zip $ZipName ${PackageContents[@]} 2>&1 >/dev/null
# Clean up intermediate files
rm ${PackageContents[@]}
exit 0

102
scripts/release.js Normal file
View File

@ -0,0 +1,102 @@
// @flow
/* eslint-disable no-console */
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable prefer-destructuring */
import '@babel/polyfill';
import fs from 'fs';
import path from 'path';
import cp from 'child_process';
import Octokit from '@octokit/rest';
import eres from 'eres';
import mime from 'mime-types';
import packageJson from '../package';
const DIST_FOLDER = path.join(__dirname, '..', './dist');
const VERSION = packageJson.version;
const GH_TOKEN = process.env.GH_TOKEN;
const OWNER = 'andrerfneves';
const PROJECT = 'zepio';
const octokit = new Octokit({ auth: GH_TOKEN });
const signBinaries = binaries => new Promise((resolve, reject) => {
const signProcess = cp.spawn(`${__dirname}/codesign.sh`, binaries);
signProcess.stdout.on('data', out => console.log('[Code Sign]', out.toString()));
signProcess.on('exit', (code) => {
if (code === 0) {
resolve(path.join(__dirname, '..', 'signatures.zip'));
} else {
reject();
}
});
});
(async () => {
const [, releasesResponse] = await eres(
octokit.repos.listReleases({
owner: OWNER,
repo: PROJECT,
}),
);
const releases = releasesResponse?.data;
if (!releases) {
console.log("Error: Can't get releases");
return;
}
const releaseWithSameTag = releases.find(cur => cur.tag_name === VERSION);
if (releaseWithSameTag) {
console.log('Warning: Already exists a release with that same tag, skipping');
return;
}
console.log(`Creating release v${VERSION}`);
const [createReleaseError, createReleaseResponse] = await eres(
octokit.repos.createRelease({
owner: OWNER,
repo: PROJECT,
tag_name: `v${VERSION}`,
name: `v${VERSION}`,
}),
);
if (createReleaseError) {
console.log('Error: ', createReleaseError);
return;
}
const files = await fs.readdirSync(DIST_FOLDER);
const binaries = files
// .filter(name => name.endsWith('.exe') || name.endsWith('.deb') || name.endsWith('.pkg'))
.map(bin => ({ path: `${DIST_FOLDER}/${bin}`, name: bin }));
const [, signaturesPath] = await eres(signBinaries(binaries.map(bin => bin.path)));
if (!signaturesPath) {
console.log("Error: Can't sign files, please verify the output");
return;
}
const filesToUpload = [...binaries, { path: signaturesPath, name: 'signatures.zip' }];
filesToUpload.forEach(async ({ path: fPath, name }) => {
const file = fs.readFileSync(fPath);
await octokit.repos.uploadReleaseAsset({
headers: {
'content-length': file.length,
'content-type': mime.lookup(fPath),
},
url: createReleaseResponse.data.upload_url,
name,
file: fs.createReadStream(fPath),
});
});
})();

View File

@ -1426,6 +1426,28 @@
version "1.1.3"
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
"@octokit/endpoint@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-4.0.0.tgz#97032a6690ef1cf9576ab1b1582c0ac837e3b5b6"
integrity sha512-b8sptNUekjREtCTJFpOfSIL4SKh65WaakcyxWzRcSPOk5RxkZJ/S8884NGZFxZ+jCB2rDURU66pSHn14cVgWVg==
dependencies:
deepmerge "3.2.0"
is-plain-object "^2.0.4"
universal-user-agent "^2.0.1"
url-template "^2.0.8"
"@octokit/request@3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-3.0.0.tgz#304a279036b2dc89e7fba7cb30c9e6a9b1f4d2df"
integrity sha512-DZqmbm66tq+a9FtcKrn0sjrUpi0UaZ9QPUCxxyk/4CJ2rseTMpAWRf6gCwOSUCzZcx/4XVIsDk+kz5BVdaeenA==
dependencies:
"@octokit/endpoint" "^4.0.0"
deprecation "^1.0.1"
is-plain-object "^2.0.4"
node-fetch "^2.3.0"
once "^1.4.0"
universal-user-agent "^2.0.1"
"@octokit/rest@^15.2.6":
version "15.18.0"
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-15.18.0.tgz#e6de702b57dec94c71e806f1cff0ecb9725b3054"
@ -1440,6 +1462,24 @@
universal-user-agent "^2.0.0"
url-template "^2.0.8"
"@octokit/rest@^16.23.4":
version "16.23.4"
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.23.4.tgz#4d8bcb1cc0cf6eeb8865632d4d60d79fc3425bbf"
integrity sha512-fQuYQ0vgNLkzeN0KEsqN0aS6EPzcuaePT5M5cE5qnKayaxFwRIQOMhNR/rTmEqo/zDK/20ZAcHsgLKodSsJtww==
dependencies:
"@octokit/request" "3.0.0"
atob-lite "^2.0.0"
before-after-hook "^1.4.0"
btoa-lite "^1.0.0"
deprecation "^1.0.1"
lodash.get "^4.4.2"
lodash.set "^4.3.2"
lodash.uniq "^4.5.0"
octokit-pagination-methods "^1.1.0"
once "^1.4.0"
universal-user-agent "^2.0.0"
url-template "^2.0.8"
"@paulcbetts/mime-db@~1.22.0":
version "1.22.4"
resolved "https://registry.yarnpkg.com/@paulcbetts/mime-db/-/mime-db-1.22.4.tgz#b8ff8e78087a40992990f702f8d9c65499be2ef1"
@ -2359,6 +2399,11 @@ asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
atob-lite@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-2.0.0.tgz#0fef5ad46f1bd7a8502c65727f0367d5ee43d696"
integrity sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=
atob@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
@ -3033,6 +3078,11 @@ before-after-hook@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.2.0.tgz#1079c10312cd4d4ad0d1676d37951ef8bfc3a563"
before-after-hook@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.4.0.tgz#2b6bf23dca4f32e628fd2747c10a37c74a4b484d"
integrity sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==
bfj@^6.1.1:
version "6.1.1"
resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.1.tgz#05a3b7784fbd72cfa3c22e56002ef99336516c48"
@ -4965,6 +5015,11 @@ deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
deepmerge@3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.2.0.tgz#58ef463a57c08d376547f8869fdc5bcee957f44e"
integrity sha512-6+LuZGU7QCNUnAJyX8cIrlzoEgggTM6B7mm+znKOX4t5ltluT9KLjN6g61ECMS0LTsLW7yDpNoxhix5FZcrIow==
deepmerge@^1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753"
@ -5073,6 +5128,11 @@ depd@^1.1.2, depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
deprecation@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-1.0.1.tgz#2df79b79005752180816b7b6e079cbd80490d711"
integrity sha512-ccVHpE72+tcIKaGMql33x5MAjKQIZrk+3x2GbJ7TeraUCZWHoT+KSZpoC+JQFsUBlSTXUrBaGiF0j6zVTepPLg==
des.js@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc"
@ -9653,6 +9713,11 @@ lodash.mergewith@^4.6.0:
version "4.6.1"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927"
lodash.set@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
lodash.sortby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
@ -10071,12 +10136,24 @@ miller-rabin@^4.0.0:
version "1.37.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8"
mime-db@~1.38.0:
version "1.38.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad"
integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==
mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19, mime-types@~2.1.7:
version "2.1.21"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96"
dependencies:
mime-db "~1.37.0"
mime-types@^2.1.22:
version "2.1.22"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd"
integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==
dependencies:
mime-db "~1.38.0"
mime@1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
@ -10397,7 +10474,7 @@ node-fetch@^1.0.1:
encoding "^0.1.11"
is-stream "^1.0.1"
node-fetch@^2.1.1, node-fetch@^2.1.2:
node-fetch@^2.1.1, node-fetch@^2.1.2, node-fetch@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5"
@ -10731,6 +10808,11 @@ obuf@^1.0.0, obuf@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
octokit-pagination-methods@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4"
integrity sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==
on-finished@^2.3.0, on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
@ -14996,6 +15078,13 @@ universal-user-agent@^2.0.0:
dependencies:
os-name "^3.0.0"
universal-user-agent@^2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-2.0.3.tgz#9f6f09f9cc33de867bb720d84c08069b14937c6c"
integrity sha512-eRHEHhChCBHrZsA4WEhdgiOKgdvgrMIHwnwnqD0r5C6AO8kwKcG7qSku3iXdhvHL3YvsS9ZkSGN8h/hIpoFC8g==
dependencies:
os-name "^3.0.0"
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"