diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 8a99644444..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,184 +0,0 @@ -version: 2.1 - -defaults: &defaults - working_directory: ~/outline - docker: - - image: cimg/node:20.10 - resource_class: large - environment: - NODE_ENV: test - DATABASE_URL: postgres://postgres:password@localhost:5432/circle_test - URL: http://localhost:3000 - NODE_OPTIONS: --max-old-space-size=8000 - -executors: - docker-publisher: - environment: - IMAGE_NAME: outlinewiki/outline - BASE_IMAGE_NAME: outlinewiki/outline-base - docker: - - image: circleci/buildpack-deps:stretch - -jobs: - build: - <<: *defaults - steps: - - checkout - - restore_cache: - key: dependency-cache-v1-{{ checksum "package.json" }} - - run: - name: install-deps - command: yarn install --frozen-lockfile - - save_cache: - key: dependency-cache-v1-{{ checksum "package.json" }} - paths: - - ./node_modules - lint: - <<: *defaults - steps: - - checkout - - restore_cache: - key: dependency-cache-v1-{{ checksum "package.json" }} - - run: - name: lint - command: yarn lint - types: - <<: *defaults - steps: - - checkout - - restore_cache: - key: dependency-cache-v1-{{ checksum "package.json" }} - - run: - name: typescript - command: yarn tsc - test-app: - <<: *defaults - steps: - - checkout - - restore_cache: - key: dependency-cache-v1-{{ checksum "package.json" }} - - run: - name: test - command: yarn test:app - test-shared: - <<: *defaults - steps: - - checkout - - restore_cache: - key: dependency-cache-v1-{{ checksum "package.json" }} - - run: - name: test - command: yarn test:shared - test-server: - <<: *defaults - parallelism: 3 - docker: - - image: cimg/node:20.10 - - image: cimg/redis:5.0 - - image: cimg/postgres:14.2 - environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: password - POSTGRES_DB: circle_test - steps: - - checkout - - restore_cache: - key: dependency-cache-v1-{{ checksum "package.json" }} - - run: - name: migrate - command: ./node_modules/.bin/sequelize db:migrate - - run: - name: test - command: | - TESTFILES=$(circleci tests glob "**/server/**/*.test.ts" | circleci tests split) - yarn test --maxWorkers=2 $TESTFILES - bundle-size: - <<: *defaults - environment: - NODE_ENV: production - steps: - - checkout - - restore_cache: - key: dependency-cache-v1-{{ checksum "package.json" }} - - run: - name: build-vite - command: yarn vite:build - - run: - name: Send bundle stats to RelativeCI - command: npx relative-ci-agent - build-image: - resource_class: xlarge - executor: docker-publisher - steps: - - checkout - - setup_remote_docker - - run: - name: Install Docker buildx - command: | - mkdir -p ~/.docker/cli-plugins - url="https://github.com/docker/buildx/releases/download/v0.8.0/buildx-v0.8.0.linux-amd64" - curl -sSL -o ~/.docker/cli-plugins/docker-buildx $url - chmod a+x ~/.docker/cli-plugins/docker-buildx - - run: - name: Enable Docker buildx - command: export DOCKER_CLI_EXPERIMENTAL=enabled - - run: - name: Initialize Docker buildx - command: | - docker buildx install - docker context create docker-multiarch - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - docker buildx create --name docker-multiarch --platform linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x docker-multiarch - docker buildx inspect --builder docker-multiarch --bootstrap - docker buildx use docker-multiarch - - run: - name: Build base image - command: docker build -f Dockerfile.base -t $BASE_IMAGE_NAME:latest --load . - - run: - name: Login to Docker Hub - command: echo "$DOCKERHUB_PASS" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin - - run: - name: Publish base Docker Image to Docker Hub - command: docker push $BASE_IMAGE_NAME:latest - - run: - name: Build and push Docker image - command: | - if [[ "$CIRCLE_TAG" == *"-"* ]]; then - docker buildx build -t $IMAGE_NAME:${CIRCLE_TAG/v/''} --platform linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x --push . - else - docker buildx build -t $IMAGE_NAME:latest -t $IMAGE_NAME:${CIRCLE_TAG/v/''} --platform linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x --push . - fi - -workflows: - version: 2 - all: - jobs: - - build - - lint: - requires: - - build - - test-server: - requires: - - build - - test-shared: - requires: - - build - - test-app: - requires: - - build - - types: - requires: - - build - - bundle-size: - requires: - - build - - types - - build-docker: - jobs: - - build-image: - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ diff --git a/.circleci/run-build-locally.sh b/.circleci/run-build-locally.sh deleted file mode 100755 index 6be7ab91c3..0000000000 --- a/.circleci/run-build-locally.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -curl --user ${CIRCLE_TOKEN}: \ - --request POST \ - --form revision=\ - --form config=@config.yml \ - --form notify=false \ - https://circleci.com/api/v1.1/project/github/outline/outline/tree/master \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..92acd7d6b9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,136 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +env: + NODE_ENV: test + DATABASE_URL: postgres://postgres:password@localhost:5432/outline_test + REDIS_URL: redis://127.0.0.1:6379 + URL: http://localhost:3000 + NODE_OPTIONS: --max-old-space-size=8000 + SECRET_KEY: F0E5AD933D7F6FD8F4DBB3E038C501C052DC0593C686D21ACB30AE205D2F634B + UTILS_SECRET: 123456 + SLACK_VERIFICATION_TOKEN: 123456 + SMTP_USERNAME: localhost + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [20.x] + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'yarn' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + lint: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: 'yarn' + - run: yarn install --frozen-lockfile + - run: yarn lint + + types: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: 'yarn' + - run: yarn install --frozen-lockfile + - run: yarn tsc + + test: + needs: build + runs-on: ubuntu-latest + strategy: + matrix: + test-group: [app, shared] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: 'yarn' + - run: yarn install --frozen-lockfile + - run: yarn test:${{ matrix.test-group }} + + test-server: + needs: build + runs-on: ubuntu-latest + services: + postgres: + image: postgres:14.2 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: password + POSTGRES_DB: outline_test + ports: + - 5432:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + redis: + image: redis:5.0 + ports: + - 6379:6379 + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + strategy: + matrix: + shard: [1, 2, 3] + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: 'yarn' + - run: yarn install --frozen-lockfile + - run: yarn sequelize db:migrate + - name: Run server tests + run: | + TESTFILES=$(find . -name "*.test.ts" -path "*/server/*" | sort | split -n -d -l $(($(find . -name "*.test.ts" -path "*/server/*" | wc -l)/${{ matrix.shard }})) - | sed -n "${{ matrix.shard }}p") + yarn test --maxWorkers=2 $TESTFILES + + bundle-size: + needs: [build, types] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: 'yarn' + - run: yarn install --frozen-lockfile + - name: Set environment to production + run: echo "NODE_ENV=production" >> $GITHUB_ENV + - run: yarn vite:build + - name: Send bundle stats to RelativeCI + run: npx relative-ci-agent diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000000..0d58a68228 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,52 @@ +name: Docker + +on: + push: + tags: + - 'v*' + +env: + IMAGE_NAME: outlinewiki/outline + BASE_IMAGE_NAME: outlinewiki/outline-base + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push base image + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile.base + push: true + tags: ${{ env.BASE_IMAGE_NAME }}:latest + platforms: linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x + + - name: Extract version + id: version + run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT + + - name: Build and push main image + uses: docker/build-push-action@v5 + with: + context: . + push: true + platforms: linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x + tags: | + ${{ env.IMAGE_NAME }}:latest + ${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}