ci: add drupal integration test workflow with issue fork support, for #71 #34
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Integration Tests | |
| # Creates real workspaces on staging-coder.ddev.com, verifies they start | |
| # correctly, then deletes them. Runs on the self-hosted sysbox runner so | |
| # the Coder provisioner can reach the local Docker/Sysbox environment. | |
| # | |
| # One-time runner setup on staging-coder.ddev.com: | |
| # # Create a dedicated low-privilege user for the runner (do not run as root or admin) | |
| # sudo apt-get install -y unzip # required by actions/checkout and other actions | |
| # sudo useradd -m -s /bin/bash github-runner | |
| # | |
| # # Register N runner instances (one per parallel matrix job — currently 2 templates). | |
| # # TODO: Revisit runner count if more templates or matrix cells are added. | |
| # # Each instance needs its own directory, a unique --name, and its own service. | |
| # # Get a fresh registration token for each from: | |
| # # https://github.com/ddev/coder-ddev/settings/actions/runners/new?arch=x64&os=linux | |
| # # https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/add-runners | |
| # for N in 1 2 3; do | |
| # sudo -u github-runner mkdir -p /home/github-runner/actions-runner-${N} | |
| # cd /home/github-runner/actions-runner-${N} | |
| # # copy runner binaries here (download once, copy to each dir) or re-download | |
| # sudo -u github-runner ./config.sh \ | |
| # --url https://github.com/ddev/coder-ddev \ | |
| # --token <token> \ | |
| # --name staging-coder-${N} \ | |
| # --labels sysbox | |
| # sudo ./svc.sh install github-runner # creates actions.runner.*.service | |
| # sudo ./svc.sh start | |
| # done | |
| # | |
| # # To remove/re-register one instance: get removal token from GitHub Settings → Actions → Runners → Remove | |
| # cd /home/github-runner/actions-runner-${N} | |
| # sudo ./svc.sh stop && sudo ./svc.sh uninstall | |
| # sudo -u github-runner ./config.sh remove --token <removal-token> | |
| # | |
| # Requires: | |
| # Repository variable: TEST_CODER_URL - https://staging-coder.ddev.com | |
| # Repository secret: OP_SERVICE_ACCOUNT_TOKEN - 1Password service account with read access | |
| # 1Password item: op://test-secrets/TEST_CODER_SESSION_TOKEN/credential | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| schedule: | |
| - cron: '0 3 * * *' | |
| workflow_dispatch: | |
| inputs: | |
| debug_enabled: | |
| description: 'Run the build with tmate set "debug_enabled"' | |
| type: boolean | |
| required: false | |
| default: false | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| integration-test: | |
| name: Integration test (${{ matrix.template }}) | |
| if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login == github.repository_owner }} | |
| runs-on: [self-hosted, sysbox] | |
| strategy: | |
| matrix: | |
| include: | |
| - template: user-defined-web | |
| extra_vars: "" | |
| extra_params: "" | |
| app_slug: "ddev-web" | |
| - template: freeform | |
| extra_vars: "" | |
| extra_params: "" | |
| app_slug: "" | |
| fail-fast: false | |
| defaults: | |
| run: | |
| shell: bash -euo pipefail {0} | |
| env: | |
| WORKSPACE_NAME: ci-${{ matrix.template }}-${{ github.run_id }} | |
| CI: "true" | |
| DDEV_NONINTERACTIVE: "true" | |
| NO_COLOR: "1" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Load 1Password secrets | |
| uses: 1password/load-secrets-action@v4 | |
| if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login == github.repository_owner }} | |
| with: | |
| export-env: true | |
| env: | |
| OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} | |
| TEST_CODER_SESSION_TOKEN: "op://test-secrets/TEST_CODER_SESSION_TOKEN/credential" | |
| - name: Login to Coder | |
| if: ${{ env.TEST_CODER_SESSION_TOKEN != '' }} | |
| run: coder login --token "${{ env.TEST_CODER_SESSION_TOKEN }}" "${{ vars.TEST_CODER_URL }}" | |
| - name: Setup tmate session | |
| uses: mxschmitt/action-tmate@v3 | |
| with: | |
| limit-access-to-actor: true | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} | |
| - name: Copy VERSION into template directory | |
| run: cp VERSION ${{ matrix.template }}/VERSION | |
| - name: Push template (inactive) | |
| run: | | |
| coder templates push ${{ matrix.template }} \ | |
| --directory ${{ matrix.template }} \ | |
| --activate=false \ | |
| --name ci-${{ github.run_id }} \ | |
| --yes \ | |
| --variable workspace_image_registry=index.docker.io/ddev/coder-ddev \ | |
| ${{ matrix.extra_vars }} | |
| - name: Create workspace | |
| run: | | |
| coder create ${{ env.WORKSPACE_NAME }} \ | |
| --template ${{ matrix.template }} \ | |
| --template-version ci-${{ github.run_id }} \ | |
| --parameter "vscode_extensions=[]" \ | |
| ${{ matrix.extra_params }} \ | |
| --yes | |
| - name: Verify workspace — agent connected | |
| run: coder ssh ${{ env.WORKSPACE_NAME }} --wait=yes -- echo "Agent connected" | |
| - name: Verify workspace — Docker daemon running | |
| run: coder ssh ${{ env.WORKSPACE_NAME }} -- docker ps | |
| - name: Verify workspace — DDEV installed | |
| run: coder ssh ${{ env.WORKSPACE_NAME }} -- ddev --version | |
| - name: Record expected host directory | |
| run: | | |
| OWNER=$(coder whoami --output json | jq -r 'if type == "array" then .[0].username else .username end') | |
| echo "OWNER=$OWNER" >> "$GITHUB_ENV" | |
| echo "HOST_DIR=/coder-workspaces/${OWNER}-${{ env.WORKSPACE_NAME }}" >> "$GITHUB_ENV" | |
| - name: Verify workspace — DDEV can start a project | |
| run: | | |
| # Write start script to runner-local file so we avoid the coder ssh heredoc+PTY hang | |
| cat > /tmp/ci-ddev-start-${{ github.run_id }}.sh << 'EOF' | |
| set -euo pipefail | |
| TESTDIR=/tmp/ci-ddev-${{ github.run_id }} | |
| echo "--- Creating test project in $TESTDIR ---" | |
| mkdir -p "$TESTDIR/web" && cd "$TESTDIR" | |
| ddev config --project-type=php --docroot=web | |
| echo "--- Starting DDEV project ---" | |
| ddev start -y | |
| echo "--- DDEV started ---" | |
| EOF | |
| scp \ | |
| -o StrictHostKeyChecking=no \ | |
| -o UserKnownHostsFile=/dev/null \ | |
| -o ProxyCommand="coder ssh --stdio ${{ env.WORKSPACE_NAME }}" \ | |
| /tmp/ci-ddev-start-${{ github.run_id }}.sh \ | |
| coder@workspace:/tmp/ci-ddev-start-${{ github.run_id }}.sh | |
| coder ssh ${{ env.WORKSPACE_NAME }} -- \ | |
| env CI=${{ env.CI }} DDEV_NONINTERACTIVE=${{ env.DDEV_NONINTERACTIVE }} NO_COLOR=${{ env.NO_COLOR }} \ | |
| bash /tmp/ci-ddev-start-${{ github.run_id }}.sh < /dev/null | |
| - name: Verify workspace — DDEV web externally accessible | |
| if: ${{ matrix.app_slug != '' }} | |
| run: | | |
| CODER_DOMAIN="${{ vars.TEST_CODER_URL }}" | |
| CODER_DOMAIN="${CODER_DOMAIN#https://}" | |
| SITE_URL="https://${{ matrix.app_slug }}--${{ env.WORKSPACE_NAME }}--${OWNER}.${CODER_DOMAIN}" | |
| echo "Checking $SITE_URL" | |
| STATUS=$(curl -s --max-time 30 -o /dev/null -w "%{http_code}" "$SITE_URL") | |
| echo "HTTP status: $STATUS" | |
| [[ "$STATUS" =~ ^[2-4] ]] || { echo "ERROR: unexpected HTTP status $STATUS" >&2; exit 1; } | |
| - name: Cleanup DDEV test project | |
| run: | | |
| coder ssh ${{ env.WORKSPACE_NAME }} -- \ | |
| env CI=${{ env.CI }} DDEV_NONINTERACTIVE=${{ env.DDEV_NONINTERACTIVE }} NO_COLOR=${{ env.NO_COLOR }} \ | |
| bash -c "cd /tmp/ci-ddev-${{ github.run_id }} && ddev delete --omit-snapshot -y && rm -rf /tmp/ci-ddev-${{ github.run_id }}" \ | |
| < /dev/null | |
| - name: Delete workspace | |
| if: always() | |
| run: coder delete ${{ env.WORKSPACE_NAME }} --yes || true | |
| - name: Verify host directory removed | |
| if: always() | |
| run: | | |
| if [[ -z "${HOST_DIR:-}" ]]; then | |
| echo "HOST_DIR not set — workspace may not have been created, skipping" | |
| exit 0 | |
| fi | |
| if [[ -d "$HOST_DIR" ]]; then | |
| echo "ERROR: Host directory was not removed by destroy provisioner: $HOST_DIR" >&2 | |
| ls -la "$HOST_DIR" >&2 || true | |
| exit 1 | |
| fi | |
| echo "OK: host directory removed: $HOST_DIR" | |
| - name: Archive CI template version | |
| if: always() | |
| run: coder templates versions archive ${{ matrix.template }} ci-${{ github.run_id }} --yes || true |