Skip to content

Commit

Permalink
feat(release): document manual release procedure
Browse files Browse the repository at this point in the history
Co-authored-by: Akos Kitta <[email protected]>
Co-authored-by: per1234 <[email protected]>

Signed-off-by: Akos Kitta <[email protected]>
  • Loading branch information
per1234 authored and Akos Kitta committed Jul 6, 2023
1 parent 95fdc59 commit a3c3b84
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/internal/Ubuntu.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ sudo apt update \
libx11-dev \
libxkbfile-dev \
build-essential \
libsecret-1-dev \
&& wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash \
&& source ~/.bashrc \
&& nvm install 16 \
Expand Down
124 changes: 124 additions & 0 deletions docs/internal/release-procedure.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,127 @@ git push origin version-<YOUR_VERSION>
```

replacing `<YOUR_VERSION>` with the version you want. Then create a PR and merge it.

## Manual build

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.

### Ubuntu 18.04
- Prerequisites:
- Ask the DevOps team for an EC2 instance with at least 8 GB of RAM.
- Your account must have access to the staging environment.
- You have VPN connection to staging.
- Setup:
- To install all required dependencies, run the following script:
```sh
sudo apt update \
&& sudo apt install --no-install-recommends --yes \
git \
gcc \
curl \
make \
python \
pkg-config \
libx11-dev \
libxkbfile-dev \
build-essential \
libsecret-1-dev \
&& wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash \
&& source ~/.bashrc \
&& nvm install 16 \
&& nvm use 16 \
&& nvm alias default 16 \
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - \
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list \
&& sudo apt update && sudo apt install --no-install-recommends yarn
```
- Set the environment variables to mimic a CI build:
```sh
export IS_RELEASE=true && export CI=true
```
- Build:
```sh
yarn --cwd ./electron/packager && yarn --cwd ./electron/packager package
```
- Artifacts:
- You have to upload the following artifacts from `./arduino-ide/electron/build/dist` to S3:
- `arduino-ide_${VERSION}_Linux_64bit.AppImage`,
- `arduino-ide_${VERSION}_Linux_64bit.zip`, and
- `stable-linux.yml`

### macOS M1
- Prerequisites:
- You need access to the shared Mac Mini at Toolbox. Use TeamViewer.
- You have access to the `FT Web Tooling` 1Password vault.
- Setup:
- 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.
- The following environment variables must be available from the shell:
- `AC_PASSWORD`: Check `Arduino Apple developer ID App Specific Password`
- `AC_USERNAME`: Check `Arduino Apple developer ID App Specific Password`
- `AC_TEAM_ID`: "KT7ZWMCJT"
- `CSC_KEY_PASSWORD`: Check `Arduino Pro IDE Apple Developer ID certificate keychain password`
- `CSC_LINK`: `Pro-IDE-Certificates.p12` file on the Mac Mini
- `IS_RELEASE`: "true"
- `CAN_SIGN`: "true"
- `MACOS_FORCE_NOTARIZE`: "true"

```sh
export AC_PASSWORD="***"
export AC_USERNAME="***"
export AC_TEAM_ID="7KT7ZWMCJT"
export CSC_KEY_PASSWORD="***"
export CSC_LINK="`pwd`/Pro-IDE-Certificates.p12"
export IS_RELEASE="true"
export CAN_SIGN="true"
export MACOS_FORCE_NOTARIZE="true"
export CI="true"
```

- Build:
```sh
yarn --cwd ./electron/packager && yarn --cwd ./electron/packager package
```

- Verify:

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.

```sh
hdiutil attach ./electron/build/dist/arduino-ide_${VERSION}_macOS_ARM64.dmg \
&& cp -R /Volumes/Arduino\ IDE\ ${VERSION}-arm64/Arduino\ IDE.app ~/Desktop \
&& hdiutil unmount /Volumes/Arduino\ IDE\ ${VERSION}-arm64 \
&& codesign -dv --verbose=4 ~/Desktop/Arduino\ IDE.app \
&& ~/Desktop/Arduino\ IDE.app/Contents/MacOS/Arduino\ IDE
```

- Cleanup:
- You **MUST** close the shell after the build.
- You **MUST** delete the `.p12` file and empty the trash afterward.

- Artifacts:
- 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`:
- `arduino-ide_${VERSION}_macOS_arm64.dmg`,
- `arduino-ide_${VERSION}_macOS_arm64.zip`, and
- `stable-mac.yml`
- To create the final channel file, do the followings:
- Copy the `stable-mac.yml` file from the Mac Mini to a folder and rename it to `stable-mac-ARM64.yml`.
- 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.
- Run the channel file merger:
```sh
node ./scripts/merge-channel-files.js ./path/to/folder/with/channel/files
```
- You have the merged channel file that you need to upload to S3.

### FAQ
- Q: I see no `stable` channel files, only `latest`.
- A: You forgot to set the `CI=true` environment variable.

----

- Q: How to connect to the EC2 instance?
- 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.

----

- Q: How to download the files from the EC2 instance?
- A: `scp -i username_ip.pem username@ip:/path/to/build/artifact /local/dir`.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"eslint-plugin-unused-imports": "^2.0.0",
"husky": "^6.0.0",
"ignore-styles": "^5.0.1",
"js-yaml": "^4.1.0",
"lerna": "^6.1.0",
"lint-staged": "^11.0.0",
"node-gyp": "^9.3.0",
Expand Down
48 changes: 48 additions & 0 deletions scripts/merge-channel-files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// @ts-check

// 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:
// - stable-mac-X64.yml
// - stable-mac-ARM64.yml
// The merged file will be saved to the folder with the name stable-mac.yml and that file can then be uploaded to S3
// The input files will be deleted if the `--no-cleanup` argument is missing.
// Usage `node ./scripts/merge-channel-files.js ./path/to/folder/with/channel/files --no-cleanup`

const yaml = require('js-yaml');
const fs = require('fs');
const path = require('path');

const args = process.argv.slice(2)
if (args.length < 1) {
console.error('Missing channel files folder path argument.');
process.exit(1);
}

const [channelFilesFolder,] = args;
// Staging file filename suffixes are named according to `runner.arch`.
// https://docs.github.com/en/actions/learn-github-actions/contexts#runner-context
const x86ChannelFilePath = path.join(channelFilesFolder, 'stable-mac-X64.yml');
const arm64ChannelFilePath = path.join(
channelFilesFolder,
'stable-mac-ARM64.yml'
);

const x86Data = yaml.load(
fs.readFileSync(x86ChannelFilePath, { encoding: 'utf8' })
);
const arm64Data = yaml.load(
fs.readFileSync(arm64ChannelFilePath, { encoding: 'utf8' })
);

const mergedData = x86Data;
mergedData['files'] = mergedData['files'].concat(arm64Data['files']);

fs.writeFileSync(
path.join(channelFilesFolder, 'stable-mac.yml'),
yaml.dump(mergedData, { lineWidth: -1 })
);

// Clean up
if (!process.argv.includes('--no-cleanup')) {
fs.rmSync(x86ChannelFilePath);
fs.rmSync(arm64ChannelFilePath);
}
2 changes: 2 additions & 0 deletions scripts/update-version.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//@ts-check

// Usage `node ./scripts/update-version.js 2.1.3`

const fs = require('fs');
const path = require('path');
const semver = require('semver');
Expand Down

0 comments on commit a3c3b84

Please sign in to comment.