From 104756c4c996e4d271d6b6bdb7e660927bf7fb0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Garc=C3=ADa=20Isa=C3=ADa?= Date: Thu, 8 Jul 2021 13:09:27 -0300 Subject: [PATCH] Move CI to Github Actions (#331) * Add Github Actions to test project can build on pushes * Checkout code before trying to build in CI * Delete old TravisCI config So long, and thanks for all the fish! * Fix NodeJS version on CI builds * Run End-to-End tests in CI using xvfb-run * Build on CI on Windows/macOS as a matrix * Preview releasing instances' build from Github Actions I've commented out the country instances for now, just in case * Expose GITHUB_TOKEN for release CI script * Release 1.2.1.1 to test new CI builds * Release 1.2.2 to test new CI releases * Test builds for staging & demo only We're still drafting the workflow, so I don't want to wait for all the instances * Build macOS releases as .pkg macOS Catalina (the oldest macOS version supported by Github Actions)[0] is not supported by our current electron-builder version to build .dmg images[1]. Upgrading electron-builder seems to require upgrading NodeJS' version - and I don't want to get lost into that rabbit hole now. The workaround is to build .pkg versions for macOS distribution - that is supported by our current electron-build [0] https://github.com/actions/virtual-environments/blob/cd920950ecab4754858eb395a1a763ae20deb342/README.md [1] https://github.com/electron-userland/electron-builder/issues/3990#issuecomment-553734294 * Run builds by platform to avoid creating multiple drafts The matrix key's order defines which job runs first[0], so this change will hopefully make all Windows builds ran before their macOS counter-parts, effectively avoiding the race condition between two `release.js` scripts listing the releases at the same time - and then both creating a draft each. It's not a hard guarantee, but if it may be a cheap workaround - and it's not that much of an issue if the workaround fail. [0] https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix * Avoid repeating INSTANCES list in Github Actions This allows us to split release creation and installers upload in two separate jobs, so we avoid creating two different drafts for each release * Test if we need to manually create the Github Release `electron-builder` must be doing it by default * Avoid creating Release Drafts from CI script electron-builder takes care of that * Move Release job into a separate workflow That'll allow us to re-run that step independently. We'll then split it into a workflow per instance. * Rollback version change It was a temporal change to be able to debug the builds. This commit rolls it back so we can merge this branch. See a2f831cf4bcae2405b6aeef4a1f695156e232f3b --- .github/workflows/build.yml | 44 ++++++++ .github/workflows/release.yml | 53 +++++++++ .travis.yml | 206 ---------------------------------- package.json | 3 + release.js | 94 ++++++---------- 5 files changed, 132 insertions(+), 268 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/release.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..24d1058 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,44 @@ +name: Build + +on: + - push + +jobs: + test: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: '10.15.3' + - name: Install dependencies + run: yarn install --ignore-engines --network-timeout 1000000 + - name: Post-install + run: yarn postinstall + - name: Lint + run: yarn lint + - name: Flow + run: yarn flow + - name: Build End-to-End Tests + run: yarn build-e2e + - name: Run End-to-End Tests + run: xvfb-run --server-args="-screen 0 1280x720x24" yarn test-e2e + build: + runs-on: ${{ matrix.os }} + needs: test + strategy: + matrix: + os: + - windows-2019 + - macos-10.15 + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: '10.15.3' + - name: Install dependencies + run: yarn install --ignore-engines --network-timeout 1000000 + - name: Post-install + run: yarn postinstall + - name: Build + run: yarn build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e22a770 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,53 @@ +name: Release + +on: + workflow_run: + workflows: ['Build'] + types: + - completed + branches: + - main + - feature/github-actions # temporal + +jobs: + release: + runs-on: ${{ matrix.os }} + if: ${{ github.event.workflow_run.conclusion == 'success' }} + strategy: + matrix: + os: + - windows-2019 + - macos-10.15 + instance: + - demo + - staging + - bf + - cm + - ga + - gh + - ke + - mw + - ng + - sl + - sn + - sz + - tz + - ug + - zm + - zw + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ github.event.workflow_run.head_sha}} + - uses: actions/setup-node@v2 + with: + node-version: '10.15.3' + - name: Install dependencies + run: yarn install --ignore-engines --network-timeout 1000000 + - name: Post-install + run: yarn postinstall + - name: Release + run: node release.js + env: + INSTANCE: ${{ matrix.instance }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 64b737c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,206 +0,0 @@ -language: node_js -node_js: -- 10.15.3 - -addons: - homebrew: - packages: - - sqlite - - sqlcipher - -stages: - - Windows - - MacOS - -jobs: - include: - - os: osx - stage: MacOS - env: - - INSTANCE=gh - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=gh YARN_GPG=no - - os: osx - stage: MacOS - env: - - INSTANCE=ga - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=ga YARN_GPG=no - - os: osx - stage: MacOS - env: - - INSTANCE=cm - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=cm YARN_GPG=no - - os: osx - stage: MacOS - env: - - INSTANCE=zm - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=zm YARN_GPG=no - - os: osx - stage: MacOS - env: - - INSTANCE=sn - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=sn YARN_GPG=no - - os: osx - stage: MacOS - env: - - INSTANCE=sl - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=sl YARN_GPG=no - - os: osx - stage: MacOS - env: - - INSTANCE=mw - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=mw YARN_GPG=no - - os: osx - stage: MacOS - env: - - INSTANCE=staging - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=staging YARN_GPG=no - - - os: osx - stage: MacOS - env: - - INSTANCE=demo - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=demo YARN_GPG=no - - - os: osx - stage: MacOS - env: - - INSTANCE=bf - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=bf YARN_GPG=no - - - os: osx - stage: MacOS - env: - - INSTANCE=zw - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=zw YARN_GPG=no - - - os: osx - stage: MacOS - env: - - INSTANCE=sz - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=sz YARN_GPG=no - - - os: osx - stage: MacOS - env: - - INSTANCE=ug - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=ug YARN_GPG=no - - os: osx - stage: MacOS - env: - - INSTANCE=tz - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=tz YARN_GPG=no - - - os: osx - stage: MacOS - env: - - INSTANCE=ke - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=ke YARN_GPG=no - - - os: osx - stage: MacOS - env: - - INSTANCE=ng - - os: windows - stage: Windows - cache: false - env: - - INSTANCE=ng YARN_GPG=no - -before_cache: - - rm -rf $HOME/.cache/electron-builder/wine - -cache: - yarn: true - directories: - - node_modules - - $(npm config get prefix)/lib/node_modules - - flow-typed - - $HOME/.cache/electron - - $HOME/.cache/electron-builder - -before_install: - - if [ "$TRAVIS_OS_NAME" == "windows" ]; then powershell -command 'Set-MpPreference -DisableRealtimeMonitoring $true'; fi - - if [ "$TRAVIS_OS_NAME" == "windows" ]; then powershell -command 'Set-MpPreference -DisableArchiveScanning $true'; fi - - if [ "$TRAVIS_OS_NAME" == "windows" ]; then powershell -command 'Set-MpPreference -DisableBehaviorMonitoring $true'; fi - - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then choco install sqlite --params "/NoTools"; fi - - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then yarn config delete proxy; fi - - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then npm config rm proxy; fi - - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then npm config rm https-proxy; fi - -install: - - yarn install --ignore-engines --network-timeout 1000000 - -script: - - yarn postinstall - - yarn lint - # # HACK: Temporarily ignore `yarn flow` on windows - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then yarn flow; fi - - yarn build-e2e - - yarn test-e2e - -after_success: - - if [[ "$TRAVIS_BRANCH" == "master" ]]; then node release.js; fi - - if [[ "$TRAVIS_BRANCH" == "release-improvement" ]]; then node release.js; fi - -notifications: - email: false diff --git a/package.json b/package.json index bcf8175..490b1dc 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,9 @@ } ] }, + "mac": { + "target": "pkg" + }, "win": { "target": [ "msi" diff --git a/release.js b/release.js index 7826aee..5200cd0 100644 --- a/release.js +++ b/release.js @@ -1,73 +1,43 @@ const { spawn } = require('child_process'); -const Octokit = require('@octokit/rest'); const fs = require('fs'); const { version } = require('./package.json'); const environments = require('./environments'); -const { GITHUB_TOKEN } = process.env; -const octokit = Octokit({ - auth: GITHUB_TOKEN, - userAgent: 'Maap collector release tool' -}); +if (!process.env.INSTANCE) { + return console.log('INSTANCE env var is missing'); +} console.log('Releasing Maap collector'); console.log(`Version ${version}`); const versionNameTag = (versionNumber, name) => `${versionNumber}-${name}`; -octokit.repos - .listReleases({ - owner: 'instedd', - repo: 'maap-collector' - }) - .then(async data => { - const { data: releases } = data; - const environment = environments.find(k => k.name === process.env.INSTANCE); - if (!process.env.INSTANCE) - return console.log('INSTANCE env var is missing'); - const versionName = versionNameTag(version, environment.name); - if (!releases.map(({ name }) => name).includes(versionName)) { - octokit.repos.createRelease({ - owner: 'instedd', - repo: 'maap-collector', - tag_name: `V${versionName}`, - draft: true, - name: versionName - }); - } - console.log(`Releasing ${versionName} with config:`); - console.log(environment.config); - - fs.writeFileSync( - './app/constants/config.override.json', - JSON.stringify(environment.config) - ); - // eslint-disable-next-line - const packageJson = require('./package.json'); - packageJson.version = versionName; - packageJson.name = `maap-collector-${process.env.INSTANCE}`; - packageJson.productName = `Maap Collector ${process.env.INSTANCE}`; - packageJson.productName = `Maap Collector ${process.env.INSTANCE}`; - packageJson.build.productName = `Maap Collector ${process.env.INSTANCE}`; - packageJson.build.appId = `org.develar.MaapCollector${process.env.INSTANCE.toUpperCase()}`; - fs.writeFileSync('./package.json', JSON.stringify(packageJson)); - await new Promise(resolve => { - const ls = spawn('yarn', ['package-ci'], { - shell: process.platform === 'win32' - }); - ls.stdout.on('data', output => { - console.log(`stdout: ${output.toString()}`); - }); +const environment = environments.find(k => k.name === process.env.INSTANCE); +const versionName = versionNameTag(version, environment.name); +console.log(`Releasing ${versionName} with config:`); +console.log(environment.config); - ls.stderr.on('data', output => { - resolve(output); - console.log(`stderr: ${output.toString()}`); - }); - - ls.on('exit', output => { - resolve(output); - console.log(`child process exited with code ${output.toString()}`); - }); - }); - return data; - }) - .catch(err => console.log(err)); +fs.writeFileSync( + './app/constants/config.override.json', + JSON.stringify(environment.config) +); +// eslint-disable-next-line +const packageJson = require('./package.json'); +packageJson.version = versionName; +packageJson.name = `maap-collector-${process.env.INSTANCE}`; +packageJson.productName = `Maap Collector ${process.env.INSTANCE}`; +packageJson.productName = `Maap Collector ${process.env.INSTANCE}`; +packageJson.build.productName = `Maap Collector ${process.env.INSTANCE}`; +packageJson.build.appId = `org.develar.MaapCollector${process.env.INSTANCE.toUpperCase()}`; +fs.writeFileSync('./package.json', JSON.stringify(packageJson)); +const packageTask = spawn('yarn', ['package-ci'], { + shell: process.platform === 'win32' +}); +packageTask.stdout.on('data', output => { + console.log(`stdout: ${output.toString()}`); +}); +packageTask.stderr.on('data', output => { + console.log(`stderr: ${output.toString()}`); +}); +packageTask.on('exit', output => { + console.log(`child process exited with code ${output.toString()}`); +});