Ports .github/workflows/ci.yml to .gitlab-ci.yml after the GitHub account
was suspended and Actions stopped being reachable. Same checks, same order.
The Actions workflow stays in the tree: it is the reference this was
written from and it works unchanged if the appeal succeeds. The image is
pinned by digest rather than tag, which is the replacement for the
workflow's SHA-pinned actions -- GitLab has no action allowlist to lean on.