feat: add official Dockerfile and release workflow for CI (fixes #85)#92
Conversation
📝 WalkthroughWalkthroughAdds a Dockerfile for becwright, a release workflow job to build and push the image to GHCR, English/Spanish documentation for Docker-based CI usage, and a CLI change introducing a custom help printer invoked for no-args or help-only invocations. ChangesOfficial Docker image and CI docs
Estimated code review effort: 2 (Simple) | ~10 minutes CLI Custom Help
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
src/becwright/cli.py (1)
1128-1133: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider passing
args_listtoparse_argsfor consistency.
args_listis computed on line 1129 butargvis passed toparse_argson line 1134. These are functionally equivalent (whenargvisNone,parse_argsalso defaults tosys.argv[1:]), but usingargs_listconsistently would make the data flow clearer and avoid a reader having to reason about the equivalence.♻️ Optional consistency tweak
- args = _build_parser().parse_args(argv) + args = _build_parser().parse_args(args_list)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/becwright/cli.py` around lines 1128 - 1133, In main, use args_list consistently when calling parse_args instead of passing argv directly. The current flow already normalizes argv into args_list and checks help options there, so updating the parse_args call to use args_list keeps the data flow clear and avoids redundant reasoning. Keep the change localized to main and preserve the existing help handling behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release.yml:
- Around line 89-95: Disable persisted checkout credentials in the Docker job by
updating the actions/checkout step so it does not leave the repo token in
.git/config before the Docker build context is sent. In the release workflow’s
checkout step, set persist-credentials to false since no later step needs git
auth, and keep the rest of the Docker login flow unchanged.
In `@Dockerfile`:
- Around line 1-12: The Dockerfile currently launches becwright as root; update
the image to create and switch to a dedicated non-root user before the
ENTRYPOINT is executed. Add the user setup in the Dockerfile around the existing
Python/git/becwright installation steps, then ensure the final runtime context
uses that user for becwright.
In `@documentation/recipes.es.md`:
- Around line 185-194: The becwright CI recipe uses `becwright check --diff
origin/main` without ensuring the base ref exists locally, so update the
`.gitlab-ci.yml` example to fetch `origin main` before running the check or
configure the `becwright` job with `GIT_DEPTH: 0`. Make the fix in the
`becwright` job snippet so the diff check has access to the full base reference.
In `@documentation/recipes.md`:
- Around line 178-187: The becwright CI job in the .gitlab-ci.yml example runs
`becwright check --diff origin/main` without ensuring the `origin/main` ref
exists locally. Update the job definition in the `becwright` example to fetch
`origin main` first or configure the job with full git history, and reference
the `becwright` job/script block so the diff check can resolve `origin/main`
correctly.
---
Nitpick comments:
In `@src/becwright/cli.py`:
- Around line 1128-1133: In main, use args_list consistently when calling
parse_args instead of passing argv directly. The current flow already normalizes
argv into args_list and checks help options there, so updating the parse_args
call to use args_list keeps the data flow clear and avoids redundant reasoning.
Keep the change localized to main and preserve the existing help handling
behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: acf1856d-36a0-40fc-8aba-3a52452395ca
📒 Files selected for processing (5)
.github/workflows/release.ymlDockerfiledocumentation/recipes.es.mddocumentation/recipes.mdsrc/becwright/cli.py
| - uses: actions/checkout@v4 | ||
| - name: Log in to GitHub Container Registry | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| registry: ghcr.io | ||
| username: ${{ github.actor }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '--- release.yml (outline) ---\n'
ast-grep outline .github/workflows/release.yml --view expanded || true
printf '\n--- release.yml (lines 1-220) ---\n'
cat -n .github/workflows/release.yml | sed -n '1,220p'Repository: DataDave-Dev/becwright
Length of output: 251
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- release.yml (outline) ---'
ast-grep outline .github/workflows/release.yml --view expanded || true
echo
echo '--- release.yml (lines 1-220) ---'
cat -n .github/workflows/release.yml | sed -n '1,220p'Repository: DataDave-Dev/becwright
Length of output: 4922
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- docker-related files ---'
git ls-files | rg '(^|/)(Dockerfile|\.dockerignore|dockerfile)(\..*)?$|^.*docker.*\.ya?ml$|^\.github/workflows/.*\.ya?ml$' || true
echo
echo '--- .dockerignore ---'
if git ls-files --error-unmatch .dockerignore >/dev/null 2>&1; then
cat -n .dockerignore
else
echo '(no .dockerignore at repo root)'
fi
echo
echo '--- Dockerfiles ---'
for f in $(git ls-files | rg '(^|/)Dockerfile(\..*)?$'); do
echo "### $f"
wc -l "$f"
sed -n '1,220p' "$f" | cat -n
echo
doneRepository: DataDave-Dev/becwright
Length of output: 852
Disable persisted checkout credentials in the Docker job. actions/checkout leaves the repo token in .git/config by default, and this workflow sends the whole repo as the Docker build context. Set persist-credentials: false here since no later step needs git auth.
🛡️ Proposed fix
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v4
+ with:
+ persist-credentials: false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - uses: actions/checkout@v4 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} |
🧰 Tools
🪛 zizmor (1.26.1)
[warning] 89-89: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 89 - 95, Disable persisted
checkout credentials in the Docker job by updating the actions/checkout step so
it does not leave the repo token in .git/config before the Docker build context
is sent. In the release workflow’s checkout step, set persist-credentials to
false since no later step needs git auth, and keep the rest of the Docker login
flow unchanged.
Source: Linters/SAST tools
| FROM python:3.12-slim | ||
|
|
||
| # Install git since becwright shells out to git commands | ||
| RUN apt-get update && \ | ||
| apt-get install -y --no-install-recommends git && \ | ||
| rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # Install becwright from PyPI | ||
| RUN pip install --no-cache-dir becwright | ||
|
|
||
| # Set entrypoint to run becwright automatically | ||
| ENTRYPOINT ["becwright"] |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Repo root files:\n'
git ls-files | sed -n '1,200p'
printf '\nDockerfile:\n'
cat -n Dockerfile
printf '\nLikely release/workflow files mentioning becwright or image publish:\n'
rg -n --hidden --glob '!**/.git/**' -e 'becwright|GHCR|ghcr|docker build|image tag|pypi|pip install' .github Dockerfile pyproject.toml setup.py setup.cfg 2>/dev/null || trueRepository: DataDave-Dev/becwright
Length of output: 8651
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'release.yml relevant section:\n'
sed -n '80,120p' .github/workflows/release.yml | cat -n
printf '\nAny Docker image build/push references:\n'
rg -n -C 3 'docker|ghcr|image|publish' .github/workflows/release.yml .github/workflows/*.yml Dockerfile action.yml README.md documentation -g '!**/node_modules/**' || true
printf '\nPyPI/package version source:\n'
sed -n '1,120p' pyproject.toml | cat -nRepository: DataDave-Dev/becwright
Length of output: 20869
Run becwright as a non-root user.
This image currently starts becwright as root. For a CI tool that processes untrusted repositories, switch to a dedicated user to reduce the blast radius of any bug or injection path.
🔒 Proposed fix
RUN pip install --no-cache-dir becwright
+RUN useradd --create-home --shell /usr/sbin/nologin becwright
+USER becwright
ENTRYPOINT ["becwright"]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| FROM python:3.12-slim | |
| # Install git since becwright shells out to git commands | |
| RUN apt-get update && \ | |
| apt-get install -y --no-install-recommends git && \ | |
| rm -rf /var/lib/apt/lists/* | |
| # Install becwright from PyPI | |
| RUN pip install --no-cache-dir becwright | |
| # Set entrypoint to run becwright automatically | |
| ENTRYPOINT ["becwright"] | |
| FROM python:3.12-slim | |
| # Install git since becwright shells out to git commands | |
| RUN apt-get update && \ | |
| apt-get install -y --no-install-recommends git && \ | |
| rm -rf /var/lib/apt/lists/* | |
| # Install becwright from PyPI | |
| RUN pip install --no-cache-dir becwright | |
| RUN useradd --create-home --shell /usr/sbin/nologin becwright | |
| USER becwright | |
| # Set entrypoint to run becwright automatically | |
| ENTRYPOINT ["becwright"] |
🧰 Tools
🪛 Trivy (0.69.3)
[error] 1-1: Image user should not be 'root'
Specify at least 1 USER command in Dockerfile with non-root user as argument
Rule: DS-0002
(IaC/Dockerfile)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Dockerfile` around lines 1 - 12, The Dockerfile currently launches becwright
as root; update the image to create and switch to a dedicated non-root user
before the ENTRYPOINT is executed. Add the user setup in the Dockerfile around
the existing Python/git/becwright installation steps, then ensure the final
runtime context uses that user for becwright.
Source: Linters/SAST tools
| Agrega el siguiente trabajo a tu `.gitlab-ci.yml`: | ||
|
|
||
| ```yaml | ||
| becwright: | ||
| stage: test | ||
| image: | ||
| name: ghcr.io/datadave-dev/becwright:latest | ||
| entrypoint: [""] | ||
| script: | ||
| - becwright check --diff origin/main |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map relevant documentation files and inspect the Spanish recipe section plus any matching English recipe.
git ls-files 'documentation/*recipes*' 'documentation/*.md' | sed -n '1,120p'
printf '\n--- Spanish recipe excerpt ---\n'
sed -n '170,210p' documentation/recipes.es.md
printf '\n--- Search for becwright / diff-based recipes ---\n'
rg -n "becwright check --diff|git fetch origin main|clone depth|fetch-depth|origin/main" documentation -SRepository: DataDave-Dev/becwright
Length of output: 2227
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n--- English recipe excerpt ---\n'
sed -n '150,195p' documentation/recipes.md
printf '\n--- GitLab/CI related lines in Spanish recipe ---\n'
sed -n '150,195p' documentation/recipes.es.mdRepository: DataDave-Dev/becwright
Length of output: 2448
🌐 Web query:
GitLab CI default checkout remote refs origin/main available GIT_DEPTH default branch checkout docs
💡 Result:
In GitLab CI/CD, the repository is typically cloned as a shallow copy, which affects the availability of remote references like origin/main [1][2]. Default Git Depth The default value for GIT_DEPTH is 20, which limits the number of commits fetched during the cloning process [3][4][2]. This value can be overridden by setting the GIT_DEPTH variable in your.gitlab-ci.yml file [3][2]. Setting it to 0 will perform a full clone of the repository, making all remote references and history available [3]. Accessing Remote Refs Because GitLab CI performs a shallow clone by default, you may find that branches or tags other than the one currently being processed are not available in the local repository [5][6]. If you need to access origin/main or other remote branches, you can: 1. Increase GIT_DEPTH or set it to 0 (full clone) to fetch more history [3]. 2. Explicitly fetch the desired branches or refs within your job script: - git fetch origin main - git fetch --all (Note: This may require specific repository access configurations depending on your runner's setup) [5]. Default Branch GitLab tracks the project's default branch via the predefined CI/CD variable CI_DEFAULT_BRANCH [7][8]. This variable is useful in conditional logic (e.g., in workflow rules) to ensure specific jobs run only when the pipeline is executing on the default branch [9][10].
Citations:
- 1: https://gitlab.com/gitlab-org/gitlab/-/issues/350100
- 2: https://sleeplessbeastie.eu/2024/07/17/how-to-create-a-shallow-clone-when-using-gitlab-ci/
- 3: https://docs.gitlab.com/ci/pipelines/settings/
- 4: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/193106
- 5: https://stackoverflow.com/questions/78787388/how-to-access-origin-main-in-gitlab-ci-cd
- 6: https://stackoverflow.com/questions/69267025/detached-head-in-gitlab-ci-pipeline-how-to-push-correctly
- 7: https://docs.gitlab.com/17.9/ci/variables/predefined_variables/
- 8: https://docs.gitlab.com/17.11/ci/variables/predefined_variables/
- 9: https://docs.gitlab.com/18.6/ci/yaml/
- 10: https://docs.gitlab.com/17.9/ci/yaml/
Fetch the base ref before the diff check
becwright check --diff origin/main can fail in GitLab CI because the default checkout is shallow, so origin/main may not be available locally. Add git fetch origin main before the check, or set GIT_DEPTH: 0 for this job.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@documentation/recipes.es.md` around lines 185 - 194, The becwright CI recipe
uses `becwright check --diff origin/main` without ensuring the base ref exists
locally, so update the `.gitlab-ci.yml` example to fetch `origin main` before
running the check or configure the `becwright` job with `GIT_DEPTH: 0`. Make the
fix in the `becwright` job snippet so the diff check has access to the full base
reference.
| Add the following job to your `.gitlab-ci.yml`: | ||
|
|
||
| ```yaml | ||
| becwright: | ||
| stage: test | ||
| image: | ||
| name: ghcr.io/datadave-dev/becwright:latest | ||
| entrypoint: [""] | ||
| script: | ||
| - becwright check --diff origin/main |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Repo files of interest:\n'
git ls-files documentation/recipes.md .gitlab-ci.yml .github/workflows 2>/dev/null | sed -n '1,200p'
printf '\n--- documentation/recipes.md around relevant lines ---\n'
wc -l documentation/recipes.md
sed -n '140,220p' documentation/recipes.md
printf '\n--- search for git fetch / depth in docs ---\n'
rg -n "git fetch|fetch-depth|clone depth|origin/main|becwright check --diff" documentation .github .gitlab-ci.yml -SRepository: DataDave-Dev/becwright
Length of output: 2834
🏁 Script executed:
#!/bin/bash
set -euo pipefail
wc -l documentation/recipes.md
sed -n '160,210p' documentation/recipes.md
rg -n "git fetch|fetch-depth|clone depth|origin/main|becwright check --diff" documentation .github .gitlab-ci.yml -SRepository: DataDave-Dev/becwright
Length of output: 1947
Fetch origin/main before the GitLab diff check. becwright check --diff origin/main needs that ref locally; add git fetch origin main or set GIT_DEPTH: 0 before running it.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@documentation/recipes.md` around lines 178 - 187, The becwright CI job in the
.gitlab-ci.yml example runs `becwright check --diff origin/main` without
ensuring the `origin/main` ref exists locally. Update the job definition in the
`becwright` example to fetch `origin main` first or configure the job with full
git history, and reference the `becwright` job/script block so the diff check
can resolve `origin/main` correctly.
Here is the complete Pull Request description ready to copy and paste into GitHub:
Description
This PR adds support for running
becwrightin containerized CI/CD environments (such as GitLab CI, Jenkins, or Docker-based runners) without needing to install Python on the host runner. It resolves #85 by distributing an official Docker image.Fixes #85
Key Changes
1. Docker Environment Setup
Dockerfile: Created at the repository root. It usespython:3.12-slimas the base, installsgit(needed forgit diffoperations in the engine), installs thebecwrightCLI package from PyPI, and sets it as the default container entrypoint.2. GitHub Actions Automated Publishing
.github/workflows/release.yml: Added a newdockerbuild-and-push job to the release pipeline. It runs after thepypijob succeeds (ensuring the latest package version is fetched from PyPI) and pushes built image tags (:latestand semantic version tags like:v1.1.0) to GitHub Container Registry (ghcr.io/datadave-dev/becwright).3. Documentation
documentation/recipes.md/recipes.es.md: Added guides (in both English and Spanish) detailing how to runbecwrightlocally via Docker and how to integrate it as a test stage in a GitLab CI pipeline.Verification Results
The Python test suite remains unaffected and fully passing:
Summary by CodeRabbit
New Features
--help.Documentation