Skip to content

Commit a3c3b84

Browse files
per1234Akos Kitta
authored and
Akos Kitta
committed
feat(release): document manual release procedure
Co-authored-by: Akos Kitta <[email protected]> Co-authored-by: per1234 <[email protected]> Signed-off-by: Akos Kitta <[email protected]>
1 parent 95fdc59 commit a3c3b84

File tree

5 files changed

+176
-0
lines changed

5 files changed

+176
-0
lines changed

Diff for: docs/internal/Ubuntu.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ sudo apt update \
1616
libx11-dev \
1717
libxkbfile-dev \
1818
build-essential \
19+
libsecret-1-dev \
1920
&& wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash \
2021
&& source ~/.bashrc \
2122
&& nvm install 16 \

Diff for: docs/internal/release-procedure.md

+124
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,127 @@ git push origin version-<YOUR_VERSION>
174174
```
175175

176176
replacing `<YOUR_VERSION>` with the version you want. Then create a PR and merge it.
177+
178+
## Manual build
179+
180+
Creating the release for Ubuntu 18.04 ([arduino/arduino-ide#2018](https://github.com/arduino/arduino-ide/issues/2018)) and macOS M1 ([arduino/arduino-ide#408](https://github.com/arduino/arduino-ide/issues/408)) is a manual procedure.
181+
182+
### Ubuntu 18.04
183+
- Prerequisites:
184+
- Ask the DevOps team for an EC2 instance with at least 8 GB of RAM.
185+
- Your account must have access to the staging environment.
186+
- You have VPN connection to staging.
187+
- Setup:
188+
- To install all required dependencies, run the following script:
189+
```sh
190+
sudo apt update \
191+
&& sudo apt install --no-install-recommends --yes \
192+
git \
193+
gcc \
194+
curl \
195+
make \
196+
python \
197+
pkg-config \
198+
libx11-dev \
199+
libxkbfile-dev \
200+
build-essential \
201+
libsecret-1-dev \
202+
&& wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash \
203+
&& source ~/.bashrc \
204+
&& nvm install 16 \
205+
&& nvm use 16 \
206+
&& nvm alias default 16 \
207+
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - \
208+
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list \
209+
&& sudo apt update && sudo apt install --no-install-recommends yarn
210+
```
211+
- Set the environment variables to mimic a CI build:
212+
```sh
213+
export IS_RELEASE=true && export CI=true
214+
```
215+
- Build:
216+
```sh
217+
yarn --cwd ./electron/packager && yarn --cwd ./electron/packager package
218+
```
219+
- Artifacts:
220+
- You have to upload the following artifacts from `./arduino-ide/electron/build/dist` to S3:
221+
- `arduino-ide_${VERSION}_Linux_64bit.AppImage`,
222+
- `arduino-ide_${VERSION}_Linux_64bit.zip`, and
223+
- `stable-linux.yml`
224+
225+
### macOS M1
226+
- Prerequisites:
227+
- You need access to the shared Mac Mini at Toolbox. Use TeamViewer.
228+
- You have access to the `FT Web Tooling` 1Password vault.
229+
- Setup:
230+
- Download the `Pro-IDE-Certificates.p12` file from `Arduino Pro IDE Apple Developer ID Certificate .p12 format` and put it somewhere on the Mac Mini. This example assumes you put the `.p12` file in the `arduino-ide` repository root, and your `cwd` is also in the `arduino-ide` repository root.
231+
- The following environment variables must be available from the shell:
232+
- `AC_PASSWORD`: Check `Arduino Apple developer ID App Specific Password`
233+
- `AC_USERNAME`: Check `Arduino Apple developer ID App Specific Password`
234+
- `AC_TEAM_ID`: "KT7ZWMCJT"
235+
- `CSC_KEY_PASSWORD`: Check `Arduino Pro IDE Apple Developer ID certificate keychain password`
236+
- `CSC_LINK`: `Pro-IDE-Certificates.p12` file on the Mac Mini
237+
- `IS_RELEASE`: "true"
238+
- `CAN_SIGN`: "true"
239+
- `MACOS_FORCE_NOTARIZE`: "true"
240+
241+
```sh
242+
export AC_PASSWORD="***"
243+
export AC_USERNAME="***"
244+
export AC_TEAM_ID="7KT7ZWMCJT"
245+
export CSC_KEY_PASSWORD="***"
246+
export CSC_LINK="`pwd`/Pro-IDE-Certificates.p12"
247+
export IS_RELEASE="true"
248+
export CAN_SIGN="true"
249+
export MACOS_FORCE_NOTARIZE="true"
250+
export CI="true"
251+
```
252+
253+
- Build:
254+
```sh
255+
yarn --cwd ./electron/packager && yarn --cwd ./electron/packager package
256+
```
257+
258+
- Verify:
259+
260+
Since you cannot drag and drop via TeamViewer, you will install the app from a command line. This example puts the IDE2 into the Desktop. Do **NOT** try to bypass the installation with a double click and open from the UI. The `node_modules` folder of the source code is implicitly in the `$PATH`, and you want to verify if the app is fully functional without the `node_modules` folder.
261+
262+
```sh
263+
hdiutil attach ./electron/build/dist/arduino-ide_${VERSION}_macOS_ARM64.dmg \
264+
&& cp -R /Volumes/Arduino\ IDE\ ${VERSION}-arm64/Arduino\ IDE.app ~/Desktop \
265+
&& hdiutil unmount /Volumes/Arduino\ IDE\ ${VERSION}-arm64 \
266+
&& codesign -dv --verbose=4 ~/Desktop/Arduino\ IDE.app \
267+
&& ~/Desktop/Arduino\ IDE.app/Contents/MacOS/Arduino\ IDE
268+
```
269+
270+
- Cleanup:
271+
- You **MUST** close the shell after the build.
272+
- You **MUST** delete the `.p12` file and empty the trash afterward.
273+
274+
- Artifacts:
275+
- You have to upload the following artifacts from `./arduino-ide/electron/build/dist` to S3, but first, you must create the final channel file from the `latest-mac.yaml`:
276+
- `arduino-ide_${VERSION}_macOS_arm64.dmg`,
277+
- `arduino-ide_${VERSION}_macOS_arm64.zip`, and
278+
- `stable-mac.yml`
279+
- To create the final channel file, do the followings:
280+
- Copy the `stable-mac.yml` file from the Mac Mini to a folder and rename it to `stable-mac-ARM64.yml`.
281+
- Download the `stable-mac.yaml` produced by GitHub Actions from the latest release, rename it to `stable-mac-X64.yml`, and put it in the same folder where you put the file from the Mac Mini.
282+
- Run the channel file merger:
283+
```sh
284+
node ./scripts/merge-channel-files.js ./path/to/folder/with/channel/files
285+
```
286+
- You have the merged channel file that you need to upload to S3.
287+
288+
### FAQ
289+
- Q: I see no `stable` channel files, only `latest`.
290+
- A: You forgot to set the `CI=true` environment variable.
291+
292+
----
293+
294+
- Q: How to connect to the EC2 instance?
295+
- A: DevOps will give you a temporary link to the private key. Create a file `username_ip.pem` in your cwd, copy the private key into the file, open a shell, and execute `ssh -i "username_ip.pem" username@ip`. DevOps will tell you the `username` and the `ip`. Do not forget the VPN.
296+
297+
----
298+
299+
- Q: How to download the files from the EC2 instance?
300+
- A: `scp -i username_ip.pem username@ip:/path/to/build/artifact /local/dir`.

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"eslint-plugin-unused-imports": "^2.0.0",
2424
"husky": "^6.0.0",
2525
"ignore-styles": "^5.0.1",
26+
"js-yaml": "^4.1.0",
2627
"lerna": "^6.1.0",
2728
"lint-staged": "^11.0.0",
2829
"node-gyp": "^9.3.0",

Diff for: scripts/merge-channel-files.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// @ts-check
2+
3+
// The script should be invoked with the path to a folder that contains the two files as an argument. The filenames in the folder should be:
4+
// - stable-mac-X64.yml
5+
// - stable-mac-ARM64.yml
6+
// The merged file will be saved to the folder with the name stable-mac.yml and that file can then be uploaded to S3
7+
// The input files will be deleted if the `--no-cleanup` argument is missing.
8+
// Usage `node ./scripts/merge-channel-files.js ./path/to/folder/with/channel/files --no-cleanup`
9+
10+
const yaml = require('js-yaml');
11+
const fs = require('fs');
12+
const path = require('path');
13+
14+
const args = process.argv.slice(2)
15+
if (args.length < 1) {
16+
console.error('Missing channel files folder path argument.');
17+
process.exit(1);
18+
}
19+
20+
const [channelFilesFolder,] = args;
21+
// Staging file filename suffixes are named according to `runner.arch`.
22+
// https://docs.github.com/en/actions/learn-github-actions/contexts#runner-context
23+
const x86ChannelFilePath = path.join(channelFilesFolder, 'stable-mac-X64.yml');
24+
const arm64ChannelFilePath = path.join(
25+
channelFilesFolder,
26+
'stable-mac-ARM64.yml'
27+
);
28+
29+
const x86Data = yaml.load(
30+
fs.readFileSync(x86ChannelFilePath, { encoding: 'utf8' })
31+
);
32+
const arm64Data = yaml.load(
33+
fs.readFileSync(arm64ChannelFilePath, { encoding: 'utf8' })
34+
);
35+
36+
const mergedData = x86Data;
37+
mergedData['files'] = mergedData['files'].concat(arm64Data['files']);
38+
39+
fs.writeFileSync(
40+
path.join(channelFilesFolder, 'stable-mac.yml'),
41+
yaml.dump(mergedData, { lineWidth: -1 })
42+
);
43+
44+
// Clean up
45+
if (!process.argv.includes('--no-cleanup')) {
46+
fs.rmSync(x86ChannelFilePath);
47+
fs.rmSync(arm64ChannelFilePath);
48+
}

Diff for: scripts/update-version.js

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//@ts-check
22

3+
// Usage `node ./scripts/update-version.js 2.1.3`
4+
35
const fs = require('fs');
46
const path = require('path');
57
const semver = require('semver');

0 commit comments

Comments
 (0)