From fda00fc87c25d285fea0ab47c82bcf0460b287d5 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Fri, 25 Nov 2022 11:04:37 -0800 Subject: [PATCH] chore: switch from circle ci to github actions (#2253) --- .circleci/config.yml | 212 ---------------------- .github/workflows/e2e-tests-readonly.yml | 65 +++++++ .github/workflows/e2e-tests-readwrite.yml | 65 +++++++ .github/workflows/unit-tests.yml | 17 ++ CONTRIBUTING.md | 4 +- README.md | 2 +- bin/clone-mastodon.js | 5 +- bin/copy-vercel-json.sh | 5 + bin/mastodon-config.js | 3 + bin/run-mastodon.js | 2 +- bin/test-vercel-json-unchanged.sh | 10 + package.json | 5 +- webpack/client.config.js | 4 +- 13 files changed, 176 insertions(+), 223 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .github/workflows/e2e-tests-readonly.yml create mode 100644 .github/workflows/e2e-tests-readwrite.yml create mode 100644 .github/workflows/unit-tests.yml create mode 100755 bin/copy-vercel-json.sh create mode 100755 bin/test-vercel-json-unchanged.sh diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 13edd388..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,212 +0,0 @@ -version: 2.1 - -orbs: - browser-tools: circleci/browser-tools@1.1.3 -workflows: - version: 2 - build_and_test: - jobs: - - build_and_unit_test - - integration_test_readonly: - requires: - - build_and_unit_test - - integration_test_readwrite: - requires: - - build_and_unit_test -executors: - node: - working_directory: ~/pinafore - docker: - - image: cimg/ruby:3.0.3-browsers - node_and_ruby: - working_directory: ~/pinafore - docker: - - image: cimg/ruby:3.0.3-browsers - - image: circleci/postgres:12.2 - environment: - POSTGRES_USER: pinafore - POSTGRES_PASSWORD: pinafore - POSTGRES_DB: pinafore_development - BROWSER: chrome:headless - - image: circleci/redis:5-alpine -commands: - install_mastodon_system_dependencies: - description: Install system dependencies that Mastodon requires - steps: - - run: - name: Install system dependencies - command: | - sudo apt-get update - sudo apt-get install -y \ - ffmpeg \ - fonts-noto-color-emoji \ - imagemagick \ - libicu-dev \ - libidn11-dev \ - libprotobuf-dev \ - postgresql-contrib \ - protobuf-compiler - install_browsers: - description: Install browsers and tools - steps: - - browser-tools/install-chrome: - chrome-version: 91.0.4472.114 - - browser-tools/install-chromedriver - - run: - name: "Check browser version" - command: | - google-chrome --version - install_node: - description: Install Node.js - steps: - - run: - name: "Install Node.js" - # via https://circleci.com/docs/2.0/circleci-images/#notes-on-pinning-images - command: | - curl -sSL "https://nodejs.org/dist/v14.21.1/node-v14.21.1-linux-x64.tar.xz" \ - | sudo tar --strip-components=2 -xJ -C /usr/local/bin/ node-v14.21.1-linux-x64/bin/node - - run: - name: Check current version of node - command: node -v - - save_workspace: - description: Persist workspace - steps: - - persist_to_workspace: - root: . - paths: - - . - load_workspace: - description: Load workspace - steps: - - attach_workspace: - at: ~/pinafore - restore_yarn_cache: - description: Restore yarn cache - steps: - - restore_cache: - name: Restore yarn cache - key: yarn-v4-{{ checksum "yarn.lock" }} - save_yarn_cache: - description: Save yarn cache - steps: - - save_cache: - name: Save yarn cache - key: yarn-v4-{{ checksum "yarn.lock" }} - paths: - - ~/.cache/yarn - restore_yarn_cache_mastodon: - description: Restore yarn cache for Mastodon - steps: - - restore_cache: - name: Restore yarn cache for Mastodon - key: yarn-v4-{{ checksum "mastodon/yarn.lock" }} - save_yarn_cache_mastodon: - description: Save yarn cache for Mastodon - steps: - - save_cache: - name: Save yarn cache for Mastodon - key: yarn-v4-{{ checksum "mastodon/yarn.lock" }} - paths: - - ~/.cache/yarn - restore_bundler_cache: - description: Restore bundler cache - steps: - - restore_cache: - name: Restore bundler cache - key: bundler-v4-{{ checksum "mastodon/Gemfile.lock" }} - save_bundler_cache: - description: Save bundler cache - steps: - - save_cache: - name: Save bundler cache - key: bundler-v4-{{ checksum "mastodon/Gemfile.lock" }} - paths: - - mastodon/vendor/bundle - install_mastodon: - description: Install Mastodon and set up Postgres/Redis - steps: - - run: - name: Clone mastodon - command: yarn clone-mastodon - - restore_yarn_cache_mastodon - - restore_bundler_cache - - run: - name: Install mastodon - command: yarn install-mastodon - - save_yarn_cache_mastodon - - save_bundler_cache - - run: - name: Wait for postgres to be ready - command: | - for i in `seq 1 10`; - do - nc -z localhost 5432 && echo Success && exit 0 - echo -n . - sleep 1 - done - echo Failed waiting for postgres && exit 1 - - run: - name: Wait for redis to be ready - command: | - for i in `seq 1 10`; - do - nc -z localhost 6379 && echo Success && exit 0 - echo -n . - sleep 1 - done - echo Failed waiting for redis && exit 1 -jobs: - build_and_unit_test: - executor: node - steps: - - checkout - - install_node - - restore_yarn_cache - - run: - name: Yarn install - command: yarn install --frozen-lockfile - - save_yarn_cache - - run: - name: Lint - command: yarn lint - - run: - name: Copy vercel.json - command: cp vercel.json vercel-old.json - - run: - name: Build - command: yarn build - - run: - name: Check vercel.json unchanged - command: | - if ! diff -q vercel-old.json vercel.json &>/dev/null; then - diff vercel-old.json vercel.json - echo "vercel.json changed, run yarn build and make sure everything looks okay" - exit 1 - fi - - run: - name: Unit tests - command: yarn test-unit - - save_workspace - integration_test_readonly: - executor: node_and_ruby - steps: - - install_mastodon_system_dependencies - - install_browsers - - install_node - - load_workspace - - install_mastodon - - run: - name: Read-only integration tests - command: yarn test-in-ci-suite0 - integration_test_readwrite: - executor: node_and_ruby - steps: - - install_mastodon_system_dependencies - - install_browsers - - install_node - - load_workspace - - install_mastodon - - run: - name: Read-write integration tests - command: yarn test-in-ci-suite1 diff --git a/.github/workflows/e2e-tests-readonly.yml b/.github/workflows/e2e-tests-readonly.yml new file mode 100644 index 00000000..92e1e4b2 --- /dev/null +++ b/.github/workflows/e2e-tests-readonly.yml @@ -0,0 +1,65 @@ +name: Read-only e2e tests +on: + pull_request: + branches: [ master ] +jobs: + test: + runs-on: ubuntu-18.04 + services: + postgres: + image: postgres:12.2 + env: + POSTGRES_USER: pinafore + POSTGRES_PASSWORD: pinafore + POSTGRES_DB: pinafore_development + POSTGRES_HOST: 127.0.0.1 + POSTGRES_PORT: 5432 + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + redis: + image: redis:5 + ports: + - 6379:6379 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '14' + - uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.0.3' + - name: Cache Mastodon bundler + uses: actions/cache@v3 + with: + path: ~/.bundle-vendor-cache + # cache based on masto version implicitly defined in mastodon-config.js + key: masto-bundler-v3-${{ hashFiles('bin/mastodon-config.js') }} + - name: Cache Mastodon's and our yarn + uses: actions/cache@v3 + with: + path: ~/.cache/yarn + # cache based on our version and masto version implicitly defined in mastodon-config.js + # because we share the yarn cache + key: masto-yarn-v1-${{ hashFiles('yarn.lock') }}-${{ hashFiles('bin/mastodon-config.js') }} + - name: Install Mastodon system dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + ffmpeg \ + fonts-noto-color-emoji \ + imagemagick \ + libicu-dev \ + libidn11-dev \ + libprotobuf-dev \ + postgresql-contrib \ + protobuf-compiler + - run: yarn --frozen-lockfile + - run: yarn build + - run: yarn clone-mastodon + - name: Move bundler cache so Mastodon can find it + run: if [ -d ~/.bundle-vendor-cache ]; then mkdir -p ./mastodon/vendor && mv ~/.bundle-vendor-cache ./mastodon/vendor/bundle; fi + - name: Read-only e2e tests + run: yarn test-in-ci-suite0 + - name: Move bundler cache so GitHub Actions can find it + run: mv ./mastodon/vendor/bundle ~/.bundle-vendor-cache diff --git a/.github/workflows/e2e-tests-readwrite.yml b/.github/workflows/e2e-tests-readwrite.yml new file mode 100644 index 00000000..76d832ff --- /dev/null +++ b/.github/workflows/e2e-tests-readwrite.yml @@ -0,0 +1,65 @@ +name: Read-write e2e tests +on: + pull_request: + branches: [ master ] +jobs: + test: + runs-on: ubuntu-18.04 + services: + postgres: + image: postgres:12.2 + env: + POSTGRES_USER: pinafore + POSTGRES_PASSWORD: pinafore + POSTGRES_DB: pinafore_development + POSTGRES_HOST: 127.0.0.1 + POSTGRES_PORT: 5432 + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + redis: + image: redis:5 + ports: + - 6379:6379 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '14' + - uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.0.3' + - name: Cache Mastodon bundler + uses: actions/cache@v3 + with: + path: ~/.bundle-vendor-cache + # cache based on masto version implicitly defined in mastodon-config.js + key: masto-bundler-v3-${{ hashFiles('bin/mastodon-config.js') }} + - name: Cache Mastodon's and our yarn + uses: actions/cache@v3 + with: + path: ~/.cache/yarn + # cache based on our version and masto version implicitly defined in mastodon-config.js + # because we share the yarn cache + key: masto-yarn-v1-${{ hashFiles('yarn.lock') }}-${{ hashFiles('bin/mastodon-config.js') }} + - name: Install Mastodon system dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + ffmpeg \ + fonts-noto-color-emoji \ + imagemagick \ + libicu-dev \ + libidn11-dev \ + libprotobuf-dev \ + postgresql-contrib \ + protobuf-compiler + - run: yarn --frozen-lockfile + - run: yarn build + - run: yarn clone-mastodon + - name: Move bundler cache so Mastodon can find it + run: if [ -d ~/.bundle-vendor-cache ]; then mkdir -p ./mastodon/vendor && mv ~/.bundle-vendor-cache ./mastodon/vendor/bundle; fi + - name: Read-write e2e tests + run: yarn test-in-ci-suite1 + - name: Move bundler cache so GitHub Actions can find it + run: mv ./mastodon/vendor/bundle ~/.bundle-vendor-cache diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 00000000..edfce81b --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,17 @@ +name: Unit tests +on: + pull_request: + branches: [ master ] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '14' + cache: 'yarn' + - run: yarn --frozen-lockfile + - run: yarn lint + - run: yarn test-vercel-json + - run: yarn test-unit diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ced15084..0cd46a24 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -120,8 +120,8 @@ or 1. Run `rm -fr mastodon` to clear out all Mastodon data 1. Comment out `await restoreMastodonData()` in `run-mastodon.js` to avoid actually populating the database with statuses/favorites/etc. -2. Update the `GIT_TAG_OR_BRANCH` in `clone-mastodon.js` to whatever you want -3. If the Ruby version changed (check Mastodon's `.ruby-version`), install it and update `RUBY_VERSION` in `mastodon-config.js` as well as the Ruby version in `.circleci/config.yml`. +2. Update the `GIT_TAG` in `mastodon-config.js` to whatever you want +3. If the Ruby version changed (check Mastodon's `.ruby-version`), install it and update `RUBY_VERSION` in `mastodon-config.js` as well as the Ruby version in `.github/workflows`. 4. Run `yarn run-mastodon` 5. Run `yarn backup-mastodon-data` to overwrite the data in `fixtures/` 6. Uncomment `await restoreMastodonData()` in `run-mastodon.js` diff --git a/README.md b/README.md index abcf2cdc..16e67074 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Pinafore [![Build status](https://circleci.com/gh/nolanlawson/pinafore.svg?style=svg)](https://app.circleci.com/pipelines/gh/nolanlawson/pinafore) +# Pinafore An alternative web client for [Mastodon](https://joinmastodon.org), focused on speed and simplicity. diff --git a/bin/clone-mastodon.js b/bin/clone-mastodon.js index 7ce9077c..b8978802 100644 --- a/bin/clone-mastodon.js +++ b/bin/clone-mastodon.js @@ -2,7 +2,7 @@ import { promisify } from 'util' import childProcessPromise from 'child-process-promise' import path from 'path' import fs from 'fs' -import { envFile, RUBY_VERSION } from './mastodon-config.js' +import { envFile, GIT_TAG, GIT_URL, RUBY_VERSION } from './mastodon-config.js' import esMain from 'es-main' const exec = childProcessPromise.exec @@ -11,9 +11,6 @@ const writeFile = promisify(fs.writeFile) const __dirname = path.dirname(new URL(import.meta.url).pathname) const dir = __dirname -const GIT_URL = 'https://github.com/tootsuite/mastodon.git' -const GIT_TAG = 'v3.5.3' - const mastodonDir = path.join(dir, '../mastodon') export default async function cloneMastodon () { diff --git a/bin/copy-vercel-json.sh b/bin/copy-vercel-json.sh new file mode 100755 index 00000000..c0b544ce --- /dev/null +++ b/bin/copy-vercel-json.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +# Designed to be run before yarn build, and then tested with test-vercel-json-unchanged.sh + +cp ./vercel.json /tmp/vercel-old.json diff --git a/bin/mastodon-config.js b/bin/mastodon-config.js index ba995936..fbf847a4 100644 --- a/bin/mastodon-config.js +++ b/bin/mastodon-config.js @@ -18,6 +18,9 @@ DB_PASS=${DB_PASS} BIND=0.0.0.0 ` +export const GIT_URL = 'https://github.com/tootsuite/mastodon.git' +export const GIT_TAG = 'v3.5.3' + export const RUBY_VERSION = '3.0.3' const __dirname = path.dirname(new URL(import.meta.url).pathname) diff --git a/bin/run-mastodon.js b/bin/run-mastodon.js index 08f7d11f..9f8a3cca 100644 --- a/bin/run-mastodon.js +++ b/bin/run-mastodon.js @@ -15,7 +15,7 @@ async function runMastodon () { const cwd = mastodonDir const promise = spawn('foreman', ['start'], { cwd, env }) // don't bother writing to mastodon.log in CI; we can't read the file anyway - const logFile = process.env.CIRCLECI ? '/dev/null' : 'mastodon.log' + const logFile = process.env.CI ? '/dev/null' : 'mastodon.log' const log = fs.createWriteStream(logFile, { flags: 'a' }) childProc = promise.childProcess childProc.stdout.pipe(log) diff --git a/bin/test-vercel-json-unchanged.sh b/bin/test-vercel-json-unchanged.sh new file mode 100755 index 00000000..46cea369 --- /dev/null +++ b/bin/test-vercel-json-unchanged.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +# In CI, we need to make sure the vercel.json file is built correctly, +# or else it will mess up the deployment to Vercel + +if ! diff -q /tmp/vercel-old.json ./vercel.json &>/dev/null; then + diff /tmp/vercel-old.json ./vercel.json + echo "vercel.json changed, run yarn build and make sure everything looks okay" + exit 1 +fi diff --git a/package.json b/package.json index fee49c09..cc35e074 100644 --- a/package.json +++ b/package.json @@ -31,11 +31,14 @@ "test-mastodon-suite0": "run-s wait-for-mastodon-to-start wait-for-mastodon-data testcafe-suite0", "test-mastodon-suite1": "run-s wait-for-mastodon-to-start wait-for-mastodon-data testcafe-suite1", "testcafe": "run-s testcafe-suite0 testcafe-suite1", - "testcafe-suite0": "cross-env-shell testcafe $BROWSER tests/spec/0*", + "testcafe-suite0": "cross-env-shell testcafe -c 2 $BROWSER tests/spec/0*", "testcafe-suite1": "cross-env-shell testcafe $BROWSER tests/spec/1*", "test-unit": "NODE_ENV=test mocha -r bin/browser-shim.js tests/unit/", "test-in-ci-suite0": "cross-env BROWSER=chrome:headless run-p --race run-mastodon start test-mastodon-suite0", "test-in-ci-suite1": "cross-env BROWSER=chrome:headless run-p --race run-mastodon start test-mastodon-suite1", + "test-vercel-json": "run-s test-vercel-json-copy build test-vercel-json-test", + "test-vercel-json-copy": "./bin/copy-vercel-json.sh", + "test-vercel-json-test": "./bin/test-vercel-json-unchanged.sh", "wait-for-mastodon-to-start": "node bin/wait-for-mastodon-to-start.js", "wait-for-mastodon-data": "node bin/wait-for-mastodon-data.js", "backup-mastodon-data": "./bin/backup-mastodon-data.sh", diff --git a/webpack/client.config.js b/webpack/client.config.js index e8c9e77e..69f8ae09 100644 --- a/webpack/client.config.js +++ b/webpack/client.config.js @@ -127,8 +127,8 @@ export default { dev && new webpack.HotModuleReplacementPlugin({ requestTimeout: 120000 }), - // generates report.html, somewhat expensive to compute, so avoid in CircleCI tests - !dev && !process.env.CIRCLECI && new BundleAnalyzerPlugin({ + // generates report.html, somewhat expensive to compute, so avoid in CI tests + !dev && !process.env.CI && new BundleAnalyzerPlugin({ analyzerMode: 'static', openAnalyzer: false, logLevel: 'silent'