Skip to content

attempt checkout store smoke test#255

Open
damienwebdev wants to merge 5 commits into
mainfrom
checkout-store-smoke-test
Open

attempt checkout store smoke test#255
damienwebdev wants to merge 5 commits into
mainfrom
checkout-store-smoke-test

Conversation

@damienwebdev
Copy link
Copy Markdown
Member

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Fixes: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@damienwebdev damienwebdev force-pushed the checkout-store-smoke-test branch from f92ae5a to caced34 Compare May 10, 2026 01:55
@damienwebdev
Copy link
Copy Markdown
Member Author

damienwebdev commented May 13, 2026

Smoke test for check-store.yaml — handoff

Goal

Add a smoke-test job to .github/workflows/check-store.yaml that, against an installed Magento store:

  • curl / → assert HTTP 200 + non-empty <title> tag
  • POST /graphql with { storeConfig { store_code } } → assert HTTP 200 + JSON path .data.storeConfig.store_code

Decisions made (locked in)

Decision Choice
Always-on vs opt-in Always-on — runs for every caller of check-store.yaml
nginx topology (B) Bridge networking + host.docker.internal (nginx in container, php-fpm on host)
nginx managed via services: block (declared in matrix) + docker restart after config write
nginx config scope conf.d/default.conf only (image's nginx.conf untouched)
Healthcheck nginx -t (validates config; passes with empty conf.d so it doesn't block GitHub's wait-for-healthy gate)
Image nginx:1.27-alpine (curl + wget both present, smaller pull)
Title assertion Non-empty <title> (regex check)
Public interface New job is a default-behavior change to a public reusable workflow; user authorized always-on

Iteration mode (file is currently broken)

.github/workflows/check-store.yaml has been stripped to a minimal smoke-only iteration form. Header in the file says "TEMP" and "REVERT before merging".

  • on: workflow_callon: push, workflow_dispatch
  • unit-test and coding-standard jobs removed
  • compute_matrix removed; smoke-test runs as a single non-matrix job
  • Magento install chain stripped — nginx serves return 200 "smoke ok\n" so we can validate the nginx pattern without Magento bootstrap cost

This breaks .github/workflows/_internal-check-store.yaml (which uses: check-store.yaml as workflow_call). That's expected during iteration.

What CI confirmed

  1. nginx -t as healthcheck works. Passes on nginx:1.27-alpine with empty conf.d (no servers = valid config).
  2. GitHub-hosted runner docker auto-creates bind-mount source paths as root-owned, mode 0755. Confirmed by CI output: Permission denied when the runner user (uid 1001) tries to write to ${{ github.workspace }}/.smoke/conf.d/default.conf after docker auto-created the dir.
  3. sudo chown workaround creates a NEW failure at the next run's actions/checkout: EACCES: permission denied, rmdir '.smoke/conf.d'. Checkout v6's workspace cleanup runs as the runner user and can't remove root-owned dirs from prior runs.

So the volume-mount-and-write-from-step pattern is unworkable on GitHub-hosted runners. Drop it.

The actual blocker right now

The current iteration form of check-store.yaml has the nginx service mounting ${{ github.workspace }}/.smoke/conf.d:/etc/nginx/conf.d and writing config from a step. After the chown attempt, actions/checkout now fails to clean the residual root-owned .smoke/conf.d from the previous run. The job won't even reach the chown step.

Recommended next step

Switch to docker cp to push config into the running nginx container, dropping the volume mount for conf.d entirely:

services:
  nginx:
    image: nginx:1.27-alpine
    ports: ['80:80']
    # NO conf.d volume mount
    options: --add-host=host.docker.internal:host-gateway --health-cmd="nginx -t" --health-interval=10s --health-retries=3 --health-timeout=5s --health-start-period=5s
- name: Push nginx config and restart
  run: |
    cat > /tmp/default.conf <<'EOF'
    server {
        listen 80 default_server;
        location / { default_type text/plain; return 200 "smoke ok\n"; }
    }
    EOF
    docker cp /tmp/default.conf nginx:/etc/nginx/conf.d/default.conf
    docker restart nginx
    # poll Health.Status until healthy

This:

  • Avoids the auto-create-as-root issue (no host-side bind for conf.d)
  • Avoids the residual-root-owned-dir checkout-cleanup issue (no host-side dir at all)
  • Keeps the workspace mount (${{ github.workspace }}:/var/www/html) for serving Magento files (workspace itself exists with runner ownership at job init, so no auto-create)

First task for the next agent: also delete the leftover root-owned .smoke/conf.d from the runner before checkout can succeed. Either:

  • Push a commit that removes the volume mount (so it stops being created), then trigger a fresh runner OR run a manual cleanup workflow
  • Or: add a pre-checkout step that does sudo rm -rf of any root-owned residue. Won't work because services start before steps; the rmdir from checkout is what fails first.

The cleanest unblock is: push a commit removing the bad volume mount entirely. The runner is fresh per job on GitHub-hosted, so a fresh runner with no volume mount will have no residue to clean. Actually — the residue concern only matters if the runner is reused (self-hosted). GitHub-hosted runners are ephemeral. If CI is failing on actions/checkout it's because GitHub is reusing a runner that has the residue, OR there's another cause. Verify by checking the actual error context in the CI logs.

Decisions still open

  1. docker cp vs docker exec heredoc — both push config into container; functionally equivalent. cp slightly cleaner.
  2. Move smoke configs to checked-in repo files — user requested earlier ("Move the smoke conf into the github repo. Same with the magento.conf."). Deferred during iteration. To restore:
    • Files at .github/smoke/conf.d/default.conf and .github/smoke/magento.conf
    • Access from a reusable workflow needs either:
      • Option A: actions/checkout repository: graycoreio/github-actions-magento2 ref: ${{ github.workflow_sha }} path: graycore-actions then reference via that path. No new public action.
      • Option B: composite action at setup-smoke-nginx/. Files auto-fetched, ${{ github.action_path }} resolves correctly. Per AGENTS.md this widens public surface — needs explicit user approval.
    • User has not chosen between A and B yet.
  3. Magento magento.conf content — minimal hand-written (just root, index, fastcgi pass) vs copy of Magento's shipped nginx.conf.sample. User has not chosen. Minimal version sketched earlier:
    root $MAGE_ROOT/pub;
    index index.php;
    location / { try_files $uri $uri/ /index.php$is_args$args; }
    location ~ \.php$ {
        fastcgi_pass fastcgi_backend;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_read_timeout 300s;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        include fastcgi_params;
    }

Production restore checklist (after iteration)

When the smoke pattern is proven, restore check-store.yaml to:

  • on: workflow_call with the original inputs (path, composer_cache_key, store_artifact_name, stamp) and composer_auth secret
  • unit-test and coding-standard jobs (in git history pre-iteration)
  • compute_matrix job that produces both matrix and smoke_matrix (latter augments services with nginx via jq)
  • smoke-test job with full Magento install chain:
    1. checkout / download-artifact
    2. setup-magento (mode: store)
    3. cache-magento
    4. composer install
    5. apt install php${PHP_VERSION}-{fpm,intl,soap,gd,curl,mbstring,xml,bcmath,zip,mysql}
    6. setup-install action (runs bin/magento setup:install)
    7. configure php-fpm pool listening on 0.0.0.0:9000, restart, TCP-probe :9000
    8. push nginx config (via docker cp per fix above), docker restart nginx, poll Health.Status
    9. curl / → assert 200 + non-empty <title>
    10. POST /graphql with storeConfig query → assert 200 + JSON path

Default base URL http://localhost/ (port 80) — nginx publishes container 80 → host 80, matches setup-install's default --base-url=http://localhost/. No extra_args needed for setup-install.

Files in play

File State
.github/workflows/check-store.yaml Currently in TEMP iteration form. Production version (with workflow_call, full input/output, unit-test, coding-standard, smoke-test) lives in git history pre-iteration (look at HEAD before the strip).
.github/workflows/_internal-check-store.yaml Untouched but currently broken (calls workflow_call signature that no longer exists during iteration).
(none yet) .github/smoke/conf.d/default.conf Not created — deferred pending decision A vs B.
(none yet) .github/smoke/magento.conf Not created — deferred pending decision on minimal vs Magento sample.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant