Skip to content

Commit 92f10e0

Browse files
author
k9ert
authored
Macos intel build (#2446)
* remove conflicting dependencies * intel preparation (untested) * make orgName more flexible to test * adjust set-version logic * build-osx package target * fix syntax * fix syntax * fix syntax * append arch for upload * syntax * syntax * fixes * fix * complete feature * fix * set-version now deleting the file instead of complaining if version-mismatch * further improvements * parametrize CI_PROJECT_ROOT_NAMESPACE with --gh-project * more fixes * tinyfix * small fix * fix packaging * fix * fix * documentation and further polishing * polishing * bugfixes and feedback * docs * more polishing * testrun * kick * kick * kick again * kick yet again * kick * kick again * kick * kick yet again * fix * kick * kick again and again * kick again * kick * kick again * kick yet again * remove comments for restriction
1 parent 7fd2b91 commit 92f10e0

17 files changed

+894
-310
lines changed

.gitlab-ci.yml

Lines changed: 32 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ release_binary_windows:
135135
- .\pyinstaller\build-win-ci.bat $CI_COMMIT_TAG
136136
- python ./utils/github.py upload ./pyinstaller/release/specterd-$CI_COMMIT_TAG-win64.zip
137137
- cd ./pyinstaller/release
138-
- python ..\..\utils\release-helper.py sha256sums specterd-$CI_COMMIT_TAG-win64.zip > SHA256SUMS-windows
138+
- python ..\..\utils\release_helper.py sha256sums specterd-$CI_COMMIT_TAG-win64.zip > SHA256SUMS-windows
139139
- type SHA256SUMS-windows
140140
- echo $GPG_PASSPHRASE | c:\Program` Files` `(x86`)\GnuPg\bin\gpg --detach-sign --armor --no-tty --batch --yes --passphrase-fd 0 --pinentry-mode loopback SHA256SUMS-windows
141141
artifacts:
@@ -222,14 +222,14 @@ release_signatures:
222222
- pip3 install -e ".[test]"
223223
- ./utils/artifact_signer.sh init # prepare .gnupg
224224
script:
225-
- python3 -m utils.release-helper download # downloads the job-artifacts from gitlab
226-
- python3 -m utils.release-helper downloadgithub # downloads additional artifacts from github (if not there and is they have SHA256SUMS-something)
227-
- python3 -m utils.release-helper checksigs # checks the signatures of all SHA256SUMM*.asc files
228-
- python3 -m utils.release-helper checkhashes # checks all SHA256SUM* files (might modify files on the fly due to windows line endings)
229-
- python3 -m utils.release-helper create # creates a SHA256SUM
225+
- python3 -m utils.release_helper download # downloads the job-artifacts from gitlab
226+
- python3 -m utils.release_helper downloadgithub # downloads additional artifacts from github (if not there and is they have SHA256SUMS-something)
227+
- python3 -m utils.release_helper checksigs # checks the signatures of all SHA256SUMM*.asc files
228+
- python3 -m utils.release_helper checkhashes # checks all SHA256SUM* files (might modify files on the fly due to windows line endings)
229+
- python3 -m utils.release_helper create # creates a SHA256SUM
230230
- ./utils/artifact_signer.sh sign --artifact ./signing_dir/SHA256SUMS # Signs the SHA256SUM
231-
- python3 -m utils.release-helper upload_shasums # uploads SHA256SUMS to github
232-
- python3 -m utils.release-helper upload_shasumssig # uploads SHA256SUMS.asc to github
231+
- python3 -m utils.release_helper upload_shasums # uploads SHA256SUMS to github
232+
- python3 -m utils.release_helper upload_shasumssig # uploads SHA256SUMS.asc to github
233233

234234
release_docker:
235235
stage: post_releasing
@@ -247,46 +247,31 @@ tag_specterext_dummy_repo:
247247
only:
248248
- tags
249249
before_script:
250-
## Install ssh-agent if not already installed, it is required by Docker.
251-
## (change apt-get to yum if you use an RPM-based image)
252-
##
253-
- 'which ssh-agent || ( apk update && apk add --no-cache bash git openssh )'
254-
- docker info
255-
256-
##
257-
## Run ssh-agent (inside the build environment)
258-
##
259-
- eval $(ssh-agent -s)
260-
261-
##
262-
## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
263-
## We're using tr to fix line endings which makes ed25519 keys work
264-
## without extra base64 encoding.
265-
## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
266-
##
267-
- echo "$SSH_SPECTEREXT_DEPLOY_KEY" | tr -d '\r' | ssh-add - > /dev/null
268-
269-
##
270-
## Create the SSH directory and give it the right permissions
271-
##
272-
- mkdir -p ~/.ssh
273-
- chmod 700 ~/.ssh
274-
275-
##
276-
## Optionally, if you will be using any Git commands, set the user name and
277-
## and email.
278-
##
279-
- git config --global user.email "specter@secretvalues"
280-
- git config --global user.name "specter"
281-
282-
##
283-
## Assuming you created the SSH_KNOWN_HOSTS variable, uncomment the
284-
## following two lines.
285-
##
286-
- echo "$KNOWN_HOSTS" > ~/.ssh/known_hosts
287-
- chmod 644 ~/.ssh/known_hosts
288-
250+
# write access to [email protected]:cryptoadvance/specterext-dummy.git
251+
- source ./utils/prepare_for_git_write.sh "$SSH_SPECTEREXT_DEPLOY_KEY"
289252
script:
290253
- echo "Now tagging ... [email protected]:${CI_PROJECT_ROOT_NAMESPACE}/specterext-dummy.git"
291254
- ./utils/tag_specterext_dummy.sh
292255

256+
update_github:
257+
stage: post_releasing
258+
only:
259+
- tags
260+
before_script:
261+
# write access to [email protected]:swan-bitcoin/specter-static.git
262+
- source ./utils/prepare_for_git_write.sh "$SSH_SPECTERSTATIC_DEPLOY_KEY"
263+
script:
264+
- echo "Now updating https://github.com:${CI_PROJECT_ROOT_NAMESPACE}/specter-desktop/releases/tag/${CI_COMMIT_TAG:-v2.0.4-pre8}"
265+
- ./utils/generate_downloadpage.sh --org_name ${CI_PROJECT_ROOT_NAMESPACE:-k9ert} --debug --version ${CI_COMMIT_TAG:-v2.0.4-pre8} generate github # default-value for testing
266+
267+
update_webpage:
268+
stage: post_releasing
269+
only:
270+
- tags
271+
before_script:
272+
# write access to [email protected]:swan-bitcoin/specter-static.git
273+
- source ./utils/prepare_for_git_write.sh "$SSH_SPECTERSTATIC_DEPLOY_KEY"
274+
script:
275+
- echo "Now updating https://github.com:${CI_PROJECT_ROOT_NAMESPACE}/specter-static.git"
276+
- ./utils/generate_downloadpage.sh --org_name ${CI_PROJECT_ROOT_NAMESPACE:-k9ert} --debug --version ${CI_COMMIT_TAG:-v2.0.4-pre8} generate webpage # default-value for testing
277+

docs/release-guide.md

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ Update your master branch after the release notes PR ([example](https://github.c
4646
git tag v1.13.1 && git push upstream v1.13.1
4747
```
4848

49+
if you have a proper setup of github- AND gitlab forks (and the remote `origin` on git pointing to your github fork), you can push that tag to origin and this is useful to test the procedures. See "CI/CD-dev-env setup" in [continuous-integration](./continuous-integration.md).
50+
51+
```bash
52+
git tag v1.13.1 && git push origin v1.13.1
53+
```
54+
4955
## GitLab - releasing stage
5056

5157
Creating a tag triggers the release process of the GitLab runners.
@@ -73,30 +79,61 @@ For details look at `.gitlab-ci.yml`
7379

7480
## MacOS
7581

76-
Ideally, directly after the tag is created, start with the MacOS release. This has to be done manually, for now. There is a script for this:
82+
Ideally, directly after the tag is created, start with the MacOS release. As the binaries of x86/arm64 are not compatible with each other, we need to build on two MacOS architectures.This has to be done manually, for now. There is a script for this. Start with the build on x86:
83+
84+
### MacOS x64 build
85+
86+
```bash
87+
./utils/build-osx.sh --version v2.0.5-pre4 specterd package upload
88+
```
89+
90+
You can also test this procedure without messing the original project via changing the `orgName` to your `orgName` in `pyinstaller/electron/downloadloc.js`.
91+
92+
This will create three artifacts on github:
93+
* specterd-v2.0.5-pre4-osx_x64.zip
94+
* SHA256SUMS-macos_x64
95+
* SHA256SUMS-macos_x64.asc
96+
97+
### MacOS arm64 build
98+
99+
The electron application will get built on the arm architecture. As it needs to store the sha256 hash in the electron-app, the make-hash target
100+
will not only hash the specterd but also download the other specterd and hash it.
77101

78102
```bash
79-
./utils/build-osx.sh --version v1.13.1 --appleid "Satoshi Nakamoto (appleid)" --mail "[email protected]" make-hash specterd electron sign upload
103+
./utils/build-osx.sh --version v2.0.5-pre4 --appleid "Satoshi Nakamoto (appleid)" --mail "[email protected]" specterd make-hash electron sign package upload
80104
```
81105

82-
This script also runs `github.py upload `, so two more binares and the hash and signature files are uploaded to GitHub:
106+
This will create four artifacts on github:
107+
* Specter-v2.0.5-pre4.dmg
108+
* specterd-v2.0.5-pre4-osx_arm64.zip
109+
* SHA256SUMS-macos_arm64
110+
* SHA256SUMS-macos_arm64.asc
83111

84-
- Specter-v1.13.1.dmg
85-
- specterd-v1.13.1-osx.zip
86-
- SHA256SUMS-macos
87-
- SHA256SUMS-macos.asc
88112

89113
## GitLab - post releasing
90114

91115
Back to GitLab, the final stage is "post releasing".
92116

93-
In this stage, the invididual SHA256-hashes and signatures are combined into two final files:
117+
### release_signatures
118+
119+
In this job, the individual SHA256-hashes and signatures are combined into two final files:
94120

95121
- SHA256SUMS
96122
- SHA256SUMS.asc
97123

98124
Everything, apart from the MacOS files, are pulled from the GitLab environment, the MacOS files from GitHub.
99-
Don't forget to delete the two MacOS files (`SHA256SUMS-macos` and `SHA256SUMS-macos.asc`) on the GitHub release page in the end.
125+
Don't forget to delete the four MacOS files (`SHA256SUMS-macos_arm64` and `SHA256SUMS-macos_arm64.asc` and the two corresponding `_x64` files) on the GitHub release page in the end.
126+
127+
This is difficult to automate as sometimes the manual steps has not succeeded while generating the SHASUM-files. As a result, those hashes are not included. So you might want to run this again. And you can, just delete the two generated files - `SHA256SUMS` and `SHA256SUMS.asc` and run the job again.
128+
129+
### release_docker
130+
131+
There are docker images created by the awesome [Chiang Mai LN dev](https://github.com/lncm/docker-specter-desktop). So the task of this job is to trigger their build-system which is done via `utils/trigger_docker_build.sh`. A prerequisite of this is a token in order to authenticate. That token is from Aaron, one of the maintainers of that repo, and can be found in the gitlab variables section of the CI/CD configuration.
132+
133+
### tag_specterext_dummy_repo
134+
135+
Sometimes there are changes on the plugin architecture. In order to create a plugin, it's quite important to know which version of the plugin system should be used. Because of that, we simply assume that the master of the [specterext-dummy](https://github.com/cryptoadvance/specterext-dummy) repo is compatible with the current master which was just tagged with the new version.
136+
So this job will tag that repo with the same tag and the creation of a plugin will take the version into account.
100137

101138
## Trouble shooting
102139

pyinstaller/build-win-ci.bat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pip3 install build==0.10.0
1919
python -m build
2020

2121
echo " --> Installing pypi package"
22-
python .\utils\release-helper.py install_wheel %1%
22+
python .\utils\release_helper.py install_wheel %1%
2323

2424
cd pyinstaller
2525

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11

2+
function orgName() {
3+
// This can be changed in order to make download possible from other github orgs
4+
return "cryptoadvance"
5+
}
6+
27
function getDownloadLocation(version, platformname) {
3-
return `https://github.com/cryptoadvance/specter-desktop/releases/download/${version}/specterd-${version}-${platformname}.zip`
8+
if (platformname != "osx") {
9+
return `https://github.com/${orgName()}/specter-desktop/releases/download/${version}/specterd-${version}-${platformname}.zip`
10+
}
11+
return `https://github.com/${orgName()}/specter-desktop/releases/download/${version}/specterd-${version}-${platformname}_${process.arch}.zip`
412
}
513

614
function appName() {
715
return "Specter"
816
}
917

1018
module.exports = {
11-
getDownloadLocation: getDownloadLocation,
12-
appName: appName
19+
getDownloadLocation,
20+
appName,
21+
orgName
1322
}
1423

pyinstaller/electron/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ app.whenReady().then(() => {
146146
if (!appSettings.versionInitialized || appSettings.versionInitialized != versionData.version) {
147147
logger.info(`Updating ${appSettingsPath} : ${JSON.stringify(appSettings)}`)
148148
appSettings.specterdVersion = versionData.version
149-
appSettings.specterdHash = versionData.sha256
149+
appSettings.specterdHash = versionData.sha256[process.arch]
150150
appSettings.versionInitialized = versionData.version
151151
fs.writeFileSync(appSettingsPath, JSON.stringify(appSettings))
152152
}
Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,60 @@
1-
const fs = require('fs')
2-
const crypto = require('crypto')
3-
const version = process.argv[2]
1+
const fs = require('fs');
2+
const crypto = require('crypto');
3+
const versionDataFile = './version-data.json';
44

55
async function setVersion() {
6-
let package = require('./package.json')
7-
package.version = version
8-
fs.writeFileSync('./package.json', JSON.stringify(package, undefined, 2))
9-
10-
if (process.argv[3]) {
11-
let versionData = {
12-
version,
13-
sha256: (await createHashFromFile(process.argv[3]))
14-
}
15-
16-
fs.writeFileSync('./version-data.json', JSON.stringify(versionData, undefined, 2))
17-
}
6+
const version = process.argv[2];
7+
const file = process.argv[3];
8+
const arch = process.argv[4] || process.arch;
9+
10+
// Set version in package.json
11+
let packageJson = require('./package.json');
12+
packageJson.version = version;
13+
fs.writeFileSync('./package.json', JSON.stringify(packageJson, undefined, 2));
14+
15+
// Set version in version-data.json
16+
if (version && file) {
17+
let versionData;
18+
try {
19+
versionData = require(versionDataFile);
20+
21+
if (versionData.version != version) {
22+
console.log(`Version mismatch. Deleting ${versionDataFile} and creating anew.`);
23+
fs.unlinkSync(versionDataFile); // Delete the existing version-data.json file
24+
versionData = createNewVersionData(version); // Create new version data object
25+
}
26+
27+
} catch (error) {
28+
console.log(`No ${versionDataFile} found. Creating anew.`);
29+
versionData = createNewVersionData(version);
30+
}
31+
// Compute SHA256 hash of the provided file
32+
versionData.sha256[arch] = await createHashFromFile(file);
33+
// Write new version data to file
34+
fs.writeFileSync(versionDataFile, JSON.stringify(versionData, undefined, 2));
35+
console.log("version-data.js: ")
36+
console.log("----------------------------------------------------------")
37+
console.log(versionData);
38+
console.log("----------------------------------------------------------")
39+
} else if (arch || file) {
40+
throw new Error("Declare both arch and file or none.");
41+
}
42+
}
43+
44+
function createNewVersionData(version) {
45+
// Return a new version data object
46+
return {
47+
version,
48+
sha256: {}
49+
};
1850
}
1951

20-
const createHashFromFile = filePath => new Promise(resolve => {
21-
const hash = crypto.createHash('sha256');
22-
fs.createReadStream(filePath).on('data', data => hash.update(data)).on('end', () => resolve(hash.digest('hex')));
52+
const createHashFromFile = filePath => new Promise((resolve, reject) => {
53+
const hash = crypto.createHash('sha256');
54+
fs.createReadStream(filePath)
55+
.on('data', data => hash.update(data))
56+
.on('end', () => resolve(hash.digest('hex')))
57+
.on('error', reject);
2358
});
2459

25-
setVersion()
60+
setVersion().catch(console.error);

pyinstaller/electron/src/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ function getAppSettings() {
4444
tor: false,
4545
proxyURL: "socks5://127.0.0.1:9050",
4646
specterdVersion: (versionData && versionData.version !== undefined) ? versionData.version : 'unknown',
47-
specterdHash: (versionData && versionData.sha256 !== undefined) ? versionData.sha256 : 'unknown',
47+
specterdHash: (versionData && versionData.sha256 !== undefined) ? versionData.sha256[process.arch] : 'unknown',
4848
specterdCLIArgs: "",
4949
versionInitialized: false
5050
}

pyinstaller/electron/src/download.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const fs = require('fs')
33
const { app, Menu } = require('electron')
44
const extract = require('extract-zip')
55
const { getDownloadLocation } = require('../downloadloc.js')
6-
const { appName, appSettings, platformName, appNameLower, versionData, versionDataPath } = require('./config.js')
6+
const { appName, appSettings, platformName, appNameLower, versionDataPath } = require('./config.js')
77
const { isMac, getFileHash } = require('./helpers.js')
88
const { logger } = require('./logging.js')
99
const ProgressBar = require('electron-progressbar')

pyinstaller/requirements.in

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,3 @@ pyinstaller==5.2
22
pefile==2022.5.30
33
macholib
44
pywin32-ctypes
5-
babel==2.12.1
6-
pytz==2022.1

pyinstaller/requirements.txt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ altgraph==0.17 \
1010
# via
1111
# macholib
1212
# pyinstaller
13-
babel==2.12.1 \
14-
--hash=sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610 \
15-
--hash=sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455
16-
# via -r requirements.in
1713
future==0.18.2 \
1814
--hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d
1915
# via pefile
@@ -43,10 +39,6 @@ pyinstaller-hooks-contrib==2022.8 \
4339
--hash=sha256:c4210fc50282c9c6a918e485e0bfae9405592390508e3be9fde19acc2213da56 \
4440
--hash=sha256:e46f099934dd4577fb1ddcf37a99fa04027c92f8f5291c8802f326345988d001
4541
# via pyinstaller
46-
pytz==2022.1 \
47-
--hash=sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7 \
48-
--hash=sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c
49-
# via -r requirements.in
5042
pywin32-ctypes==0.2.0 \
5143
--hash=sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942 \
5244
--hash=sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98

0 commit comments

Comments
 (0)