mirror of
https://github.com/ubicloud/ubicloud.git
synced 2025-10-07 07:11:58 +08:00
We use our internal MinIO cluster to distribute images to our fleet. It has a unique use case where we download a single large file repeatedly, which impacts cluster performance and degrades the experience for other users. We decided to move image distribution to Cloudflare R2. This commit enables generating presigned URLs for R2.
167 lines
7 KiB
YAML
167 lines
7 KiB
YAML
name: E2E CI
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
test_cases:
|
|
description: 'Comma-separated list of test cases (vm)'
|
|
required: true
|
|
default: 'vm,github_runner_ubuntu_2404,github_runner_ubuntu_2204,postgres_standard,postgres_ha'
|
|
type: string
|
|
|
|
schedule:
|
|
- cron: '0 */2 * * *'
|
|
|
|
jobs:
|
|
run-ci:
|
|
if: vars.RUN_E2E == 'true'
|
|
runs-on: ubicloud-standard-4
|
|
environment: E2E-CI
|
|
timeout-minutes: 60
|
|
concurrency: e2e_environment
|
|
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@v5
|
|
|
|
- name: Set up Clover
|
|
uses: ./.github/actions/setup-clover
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version-file: "package.json"
|
|
cache: "npm"
|
|
|
|
- name: Install node packages
|
|
run: npm ci
|
|
|
|
- name: Build assets
|
|
run: npm run prod
|
|
|
|
- name: Install cloudflared
|
|
run: curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb && sudo dpkg -i cloudflared.deb
|
|
|
|
- name: Set cloudflared token
|
|
run: sudo cloudflared service install ${{ secrets.CLOUDFLARED_TOKEN }}
|
|
|
|
- name: Install mailpit
|
|
run: |
|
|
curl -sfL -m 90 -o mailpit.tar.gz https://github.com/axllent/mailpit/releases/download/v1.27.0/mailpit-linux-amd64.tar.gz
|
|
tar zxf mailpit.tar.gz
|
|
mv mailpit /usr/local/bin/
|
|
sudo systemd-run --setenv="MP_UI_AUTH=${{ secrets.MAIL_USER }}:${{ secrets.MAIL_PASSWORD }}" \
|
|
--setenv="MP_SMTP_AUTH=${{ secrets.MAIL_USER }}:${{ secrets.MAIL_PASSWORD }}" --setenv="MP_SMTP_AUTH_ALLOW_INSECURE=true" \
|
|
--unit mailpit -- mailpit
|
|
|
|
- name: Install foreman
|
|
run: gem install foreman
|
|
|
|
- name: Modify Procfile to add retry logic
|
|
run: |
|
|
sed -i "s/^\([^:]*\): \(.*\)/\1: bash -c 'for i in {1..4}; do \2 \&\& break || echo \"Attempt \$i failed, retrying...\"; sleep 1; done'/" Procfile
|
|
|
|
- name: Add e2e script to Procfile
|
|
run: |
|
|
test_cases="$(yq -r '[.[].name] | join(",")' config/e2e_test_cases.yml)"
|
|
if [[ "${{ github.event_name }}" == "workflow_dispatch" && -n "${{ inputs.test_cases }}" ]]; then
|
|
test_cases="${{ inputs.test_cases }}"
|
|
fi
|
|
echo "Running e2e test cases: $test_cases"
|
|
echo "e2e: bin/e2e --test-cases=$test_cases" >> Procfile
|
|
|
|
- name: Run tests
|
|
env:
|
|
BASE_URL: https://${{ secrets.CLOUDFLARED_ADDRESS }}
|
|
CLOVER_DATABASE_URL: postgres:///clover_test?user=clover
|
|
RACK_ENV: production
|
|
IS_E2E: "true"
|
|
DISPATCHER_MAX_THREADS: 16
|
|
E2E_HETZNER_SERVER_ID: ${{ secrets.E2E_HETZNER_SERVER_ID }}
|
|
E2E_GITHUB_INSTALLATION_ID: ${{ secrets.E2E_GH_INSTALLATION_ID }}
|
|
HETZNER_SSH_PUBLIC_KEY: ${{ secrets.HETZNER_SSH_PUBLIC_KEY }}
|
|
HETZNER_SSH_PRIVATE_KEY: ${{ secrets.HETZNER_SSH_PRIVATE_KEY }}
|
|
HETZNER_USER: ${{ secrets.HETZNER_USER }}
|
|
HETZNER_PASSWORD: ${{ secrets.HETZNER_PASSWORD }}
|
|
UBICLOUD_IMAGES_BLOB_STORAGE_ENDPOINT: ${{ secrets.UBICLOUD_IMAGES_BLOB_STORAGE_ENDPOINT }}
|
|
UBICLOUD_IMAGES_BLOB_STORAGE_ACCESS_KEY: ${{ secrets.UBICLOUD_IMAGES_BLOB_STORAGE_ACCESS_KEY }}
|
|
UBICLOUD_IMAGES_BLOB_STORAGE_SECRET_KEY: ${{ secrets.UBICLOUD_IMAGES_BLOB_STORAGE_SECRET_KEY }}
|
|
UBICLOUD_IMAGES_BLOB_STORAGE_CERTS: ${{ secrets.UBICLOUD_IMAGES_BLOB_STORAGE_CERTS }}
|
|
UBICLOUD_IMAGES_R2_BUCKET_NAME: ${{ secrets.UBICLOUD_IMAGES_R2_BUCKET_NAME }}
|
|
UBICLOUD_IMAGES_R2_ENDPOINT: ${{ secrets.UBICLOUD_IMAGES_R2_ENDPOINT }}
|
|
UBICLOUD_IMAGES_R2_ACCESS_KEY: ${{ secrets.UBICLOUD_IMAGES_R2_ACCESS_KEY }}
|
|
UBICLOUD_IMAGES_R2_SECRET_KEY: ${{ secrets.UBICLOUD_IMAGES_R2_SECRET_KEY }}
|
|
GITHUB_APP_NAME: ${{ secrets.GH_APP_NAME }}
|
|
GITHUB_APP_ID: ${{ secrets.GH_APP_ID }}
|
|
GITHUB_APP_CLIENT_ID: ${{ secrets.GH_APP_CLIENT_ID }}
|
|
GITHUB_APP_CLIENT_SECRET: ${{ secrets.GH_APP_CLIENT_SECRET }}
|
|
GITHUB_APP_PRIVATE_KEY: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
|
GITHUB_APP_WEBHOOK_SECRET: ${{ secrets.GH_APP_WEBHOOK_SECRET }}
|
|
GITHUB_RUNNER_SERVICE_PROJECT_ID: "89841457-35a2-8ed2-a88a-424ea5ddd83b"
|
|
GITHUB_CACHE_BLOB_STORAGE_ENDPOINT: ${{ secrets.GH_CACHE_BLOB_STORAGE_ENDPOINT }}
|
|
GITHUB_CACHE_BLOB_STORAGE_REGION: ${{ secrets.GH_CACHE_BLOB_STORAGE_REGION }}
|
|
GITHUB_CACHE_BLOB_STORAGE_ACCESS_KEY: ${{ secrets.GH_CACHE_BLOB_STORAGE_ACCESS_KEY }}
|
|
GITHUB_CACHE_BLOB_STORAGE_SECRET_KEY: ${{ secrets.GH_CACHE_BLOB_STORAGE_SECRET_KEY }}
|
|
GITHUB_CACHE_BLOB_STORAGE_ACCOUNT_ID: ${{ secrets.GH_CACHE_BLOB_STORAGE_ACCOUNT_ID }}
|
|
GITHUB_CACHE_BLOB_STORAGE_API_KEY: ${{ secrets.GH_CACHE_BLOB_STORAGE_API_KEY }}
|
|
POSTGRES_SERVICE_PROJECT_ID: "546a1ed8-53e5-86d2-966c-fb782d2ae5ab"
|
|
MINIO_SERVICE_PROJECT_ID: "37ad2a8d-0220-4e8b-a67f-38db95d6c657"
|
|
VM_POOL_PROJECT_ID: "e4b93fb7-5125-8ad2-9d29-730ff4506bc3"
|
|
MAIL_FROM: test@example.com
|
|
SMTP_USER: ${{ secrets.MAIL_USER }}
|
|
SMTP_PASSWORD: ${{ secrets.MAIL_PASSWORD }}
|
|
SMTP_HOSTNAME: localhost
|
|
SMTP_PORT: 1025
|
|
SMTP_TLS: false
|
|
STRIPE_PUBLIC_KEY: ${{ secrets.STRIPE_PUBLIC_KEY }}
|
|
STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }}
|
|
VHOST_BLOCK_BACKEND_VERSION: v0.2.0
|
|
run: |
|
|
set -o pipefail
|
|
timeout 55m foreman start -m all=1,respirate=2 | tee foreman.log | grep --line-buffered -F "e2e.1"
|
|
|
|
- name: Print logs
|
|
if: always()
|
|
run: grep -h -v -E "sleep_duration_sec|monitor.1" foreman.log
|
|
|
|
- name: Extract image download time
|
|
if: always()
|
|
id: extract_download
|
|
run: |
|
|
download_time="$(grep "VmHost.wait_download_boot_images" foreman.log | cut -d'|' -f2 | tail -1)"
|
|
echo "### Image downloaded in $download_time" >> $GITHUB_STEP_SUMMARY
|
|
echo "DOWNLOAD_TIME=$download_time" >> $GITHUB_OUTPUT
|
|
|
|
- name: Upload logs
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: e2e-${{ github.run_id }}-logs
|
|
path: foreman.log
|
|
|
|
- name: Send notification if failed
|
|
if: ${{ failure() && github.ref_name == 'main' }}
|
|
uses: slackapi/slack-github-action@v2.1.1
|
|
with:
|
|
webhook: ${{ secrets.SLACK_WEBHOOK_PAGER_URL }}
|
|
webhook-type: incoming-webhook
|
|
payload: |
|
|
text: "*E2E Tests Failed* :this-is-fine-fire:"
|
|
attachments:
|
|
- color: "E33122"
|
|
fields:
|
|
- title: "Event"
|
|
short: true
|
|
value: "${{ github.event_name }}"
|
|
- title: "Reference"
|
|
short: true
|
|
value: "<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.ref_name }}>"
|
|
- title: "Action"
|
|
short: true
|
|
value: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ github.workflow }}>"
|
|
- title: "Download Time"
|
|
short: true
|
|
value: "${{ steps.extract_download.outputs.DOWNLOAD_TIME }}"
|