name: Test Suite on: pull_request: push: branches: - main - 'v5.*' - 3.x - 2.x - 'renovate/*' env: FORCE_COLOR: 1 concurrency: group: ${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: lint: runs-on: ubuntu-latest if: github.event_name == 'push' || (github.event_name == 'pull_request' && !startsWith(github.head_ref, 'renovate/')) name: Lint steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 env: FORCE_COLOR: 0 with: node-version: '16.13.0' cache: yarn - uses: actions/cache@v3 with: path: ghost/**/.eslintcache key: eslint-cache - run: yarn --prefer-offline - run: yarn lint - uses: daniellockyer/action-slack-build@master if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' with: status: ${{ job.status }} env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} admin-tests: runs-on: ubuntu-latest if: github.event_name == 'push' || (github.event_name == 'pull_request' && !startsWith(github.head_ref, 'renovate/')) name: Admin - Chrome env: MOZ_HEADLESS: 1 JOBS: 1 CI: true COVERAGE: true steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: "16.13.0" - run: yarn --prefer-offline - run: yarn workspace ghost-admin run test env: BROWSER: Chrome # Merge coverage reports and upload - run: yarn ember coverage-merge working-directory: ghost/admin - uses: actions/upload-artifact@v3 with: name: coverage path: ghost/*/coverage/cobertura-coverage.xml - uses: daniellockyer/action-slack-build@master if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' with: status: ${{ job.status }} env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} migrations: runs-on: ubuntu-latest defaults: run: working-directory: ghost/core if: github.event_name == 'push' || (github.event_name == 'pull_request' && !startsWith(github.head_ref, 'renovate/')) strategy: matrix: env: - DB: sqlite3 DB_CLIENT: sqlite3 - DB: mysql8 DB_CLIENT: mysql env: database__client: ${{ matrix.env.DB_CLIENT }} name: Migrations (${{ matrix.env.DB }}) steps: - uses: actions/checkout@v3 with: fetch-depth: 0 submodules: true - uses: actions/setup-node@v3 env: FORCE_COLOR: 0 with: node-version: '16.13.0' cache: yarn - name: Shutdown MySQL run: sudo service mysql stop if: matrix.env.DB == 'mysql8' - uses: daniellockyer/mysql-action@main if: matrix.env.DB == 'mysql8' with: authentication plugin: 'caching_sha2_password' mysql version: '8.0' mysql database: 'ghost_testing' mysql root password: 'root' - name: Set env vars (SQLite) if: contains(matrix.env.DB, 'sqlite') run: echo "database__connection__filename=/dev/shm/ghost-test.db" >> $GITHUB_ENV - name: Set env vars (MySQL) if: contains(matrix.env.DB, 'mysql') run: | echo "database__connection__host=127.0.0.1" >> $GITHUB_ENV echo "database__connection__user=root" >> $GITHUB_ENV echo "database__connection__password=root" >> $GITHUB_ENV echo "database__connection__database=ghost_testing" >> $GITHUB_ENV - run: yarn --prefer-offline - run: | node index.js & sleep 20 && { kill $! && wait $!; } 2>/dev/null - run: sqlite3 ${{ env.database__connection__filename }} "DELETE FROM migrations WHERE version LIKE '5.%';" if: matrix.env.DB == 'sqlite3' - run: mysql -h127.0.0.1 -uroot -proot ghost_testing -e "DELETE FROM migrations WHERE version LIKE '5.%';" if: matrix.env.DB == 'mysql8' - run: yarn knex-migrator migrate --force unit-tests: runs-on: ubuntu-latest if: github.event_name == 'push' || (github.event_name == 'pull_request' && !startsWith(github.head_ref, 'renovate/')) strategy: matrix: node: [ '14.18.0', '16.13.0', '18.12.1' ] name: Unit Tests (Node ${{ matrix.node }}) steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 env: FORCE_COLOR: 0 with: node-version: ${{ matrix.node }} cache: yarn - run: yarn --prefer-offline - run: yarn test:unit - uses: actions/upload-artifact@v3 if: startsWith(matrix.node, '16') with: name: coverage path: ghost/*/coverage/cobertura-coverage.xml - uses: daniellockyer/action-slack-build@master if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' with: status: ${{ job.status }} env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} database-tests: runs-on: ubuntu-latest defaults: run: working-directory: ghost/core if: github.event_name == 'push' || (github.event_name == 'pull_request' && !startsWith(github.head_ref, 'renovate/')) strategy: matrix: node: [ '14.18.0', '16.13.0', '18.12.1' ] env: - DB: mysql8 NODE_ENV: testing-mysql include: - node: 16.13.0 env: DB: sqlite3 NODE_ENV: testing env: DB: ${{ matrix.env.DB }} NODE_ENV: ${{ matrix.env.NODE_ENV }} name: Database Tests (Node ${{ matrix.node }}, ${{ matrix.env.DB }}) steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 env: FORCE_COLOR: 0 with: node-version: ${{ matrix.node }} cache: yarn - name: Shutdown MySQL run: sudo service mysql stop if: matrix.env.DB == 'mysql8' - uses: daniellockyer/mysql-action@main if: matrix.env.DB == 'mysql8' with: authentication plugin: 'caching_sha2_password' mysql version: '8.0' mysql database: 'ghost_testing' mysql root password: 'root' - run: yarn --prefer-offline - run: date +%s > ${{ runner.temp }}/startTime # Get start time for test suite - name: Set env vars (SQLite) if: contains(matrix.env.DB, 'sqlite') run: echo "database__connection__filename=/dev/shm/ghost-test.db" >> $GITHUB_ENV - name: Set env vars (MySQL) if: contains(matrix.env.DB, 'mysql') run: echo "database__connection__password=root" >> $GITHUB_ENV - name: Run tests run: yarn test:ci # Get runtime in seconds for test suite - run: | startTime="$(cat ${{ runner.temp }}/startTime)" endTime="$(date +%s)" echo "test_time=$(($endTime-$startTime))" >> $GITHUB_ENV - uses: codecov/codecov-action@v3 if: startsWith(matrix.node, '16') && contains(matrix.env.DB, 'mysql') with: flags: e2e-tests # Continue on error if TailScale service is down - name: Tailscale Action timeout-minutes: 2 continue-on-error: true if: (github.event_name == 'push' && github.repository_owner == 'TryGhost') || (github.event_name == 'pull_request' && startsWith(github.head_ref, 'TryGhost/')) uses: tailscale/github-action@v1 with: authkey: ${{ secrets.TAILSCALE_AUTHKEY }} # Report time taken to metrics service # Continue on error if previous TailScale step fails - uses: tryghost/action-trigger-metric@main timeout-minutes: 1 continue-on-error: true if: (github.event_name == 'push' && github.repository_owner == 'TryGhost') || (github.event_name == 'pull_request' && startsWith(github.head_ref, 'TryGhost/')) with: metricName: 'test-time' metricValue: ${{ env.test_time }} configuration: | { "metrics": { "transports": ["elasticsearch"], "metadata": { "database": "${{ matrix.env.DB }}", "node": "${{ matrix.node }}" } }, "elasticsearch": { "host": "${{ secrets.ELASTICSEARCH_HOST }}", "username": "${{ secrets.ELASTICSEARCH_USERNAME }}", "password": "${{ secrets.ELASTICSEARCH_PASSWORD }}" } } - uses: daniellockyer/action-slack-build@master if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' with: status: ${{ job.status }} env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} ghost-cli: name: Ghost-CLI if: github.event_name == 'push' || (github.event_name == 'pull_request' && !startsWith(github.head_ref, 'renovate/')) runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: fetch-depth: 0 submodules: true - uses: actions/setup-node@v3 env: FORCE_COLOR: 0 with: node-version: '16.13.0' cache: yarn - name: Install Ghost-CLI run: npm install -g ghost-cli@latest - run: yarn --prefer-offline - run: npm --no-git-tag-version version minor # We need to artificially bump the minor version to get migrations to run working-directory: ghost/core - run: npm pack working-directory: ghost/core - run: mv ghost-*.tgz ghost.tgz working-directory: ghost/core - name: Clean Install run: | DIR=$(mktemp -d) ghost install local -d $DIR --archive $(pwd)/ghost/core/ghost.tgz - name: Latest Release run: | DIR=$(mktemp -d) ghost install local -d $DIR ghost update -d $DIR --archive $(pwd)/ghost/core/ghost.tgz - name: Update from latest v4 run: | DIR=$(mktemp -d) ghost install v4 --local -d $DIR ghost update -f -d $DIR --archive $(pwd)/ghost/core/ghost.tgz - name: Print debug logs if: failure() run: | [ -f ~/.ghost/logs/*.log ] && cat ~/.ghost/logs/*.log - uses: daniellockyer/action-slack-build@master if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' with: status: ${{ job.status }} env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} coverage: name: Coverage needs: [unit-tests, admin-tests] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Restore coverage uses: actions/download-artifact@v3 with: path: ghost - run: rsync -av --remove-source-files ghost/coverage/* ghost/ - uses: codecov/codecov-action@v3 with: flags: unit-tests canary: needs: [lint, ghost-cli, admin-tests, migrations, unit-tests, database-tests] if: github.event_name == 'push' && github.ref == 'refs/heads/main' name: Canary secrets: inherit uses: tryghost/actions/.github/workflows/canary.yml@main