diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..332d3e4 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,43 @@ +## What I built +- Implemented `get_config`, `upload_raw_to_blob`, `write_to_postgres` in `src/pipeline.py` +- Pinned `azure-storage-blob` and `psycopg2-binary` in `requirements.txt` +- Cache-friendly `Dockerfile` +- Deployed as an Azure Container App Job (Task 4-5) +- Execution-history portal screenshot: `docs/execution_history.png` +- AI usage: `AI_ASSIST.md` + +## How to review +- Code: read `src/pipeline.py` (blob upload + Postgres upsert). +- Azure result: see `docs/execution_history.png` (the Container App Job execution history). +- AI usage: `AI_ASSIST.md`. + +## How to run +From a clean clone, with your own Azure Blob + Postgres access: + +```bash +python -m venv .venv && source .venv/bin/activate +pip install -r requirements.txt +cp .env.example .env # fill in your own Blob + Postgres connection strings +set -a && source .env && set +a +python -m src.pipeline +``` + +> Data dependency: this needs your own Blob container and Postgres connection strings. A reviewer without them relies on the committed execution-history screenshot as the canonical evidence. + +## What reviewers should see (expected results) +Fill in what your run actually produces: +- Rows written to Postgres: +- Blob(s) written (name / count): +- Container App Job status in the screenshot: + +## Known limitations / out of scope +- +- Write "none" if everything in the assignment is done and working. + +## Extra completed +- [ ] Any bonus / stretch items from the chapter + +## Self-check +- [ ] `bash .hyf/test.sh` passes +- [ ] No credentials committed (no connection strings in code, `.env` is gitignored) +- [ ] `docs/execution_history.png` shows a successful job execution diff --git a/.github/workflows/pr-body-check.yml b/.github/workflows/pr-body-check.yml new file mode 100644 index 0000000..8d066d9 --- /dev/null +++ b/.github/workflows/pr-body-check.yml @@ -0,0 +1,52 @@ +name: PR body check + +# Fails the check when a pull request description is missing the sections from +# .github/PULL_REQUEST_TEMPLATE.md. GitHub only auto-fills that template in the +# web "compose" form and in `gh pr create` with no --body; a PR opened through +# the REST API or `gh pr create --body "..."` (the path most AI tools take) +# silently skips it. This check is the only thing that actually enforces it. +# +# Recovery is automatic: editing the PR description fires the `edited` event and +# re-runs this check with the new body. No new commit or manual re-run needed. + +on: + pull_request: + types: [opened, edited, reopened, synchronize] + branches: [main] + +permissions: + contents: read + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Check required sections are present + env: + PR_BODY: ${{ github.event.pull_request.body }} + run: | + set -euo pipefail + required=( + "## What I built" + "## How to review" + "## How to run" + "## What reviewers should see" + "## Self-check" + ) + missing=() + for section in "${required[@]}"; do + if ! printf '%s' "$PR_BODY" | grep -qiF "$section"; then + missing+=("$section") + fi + done + if [ ${#missing[@]} -ne 0 ]; then + echo "::error::Your PR description is missing required sections. Start from the template (.github/PULL_REQUEST_TEMPLATE.md) and keep these headings:" + for m in "${missing[@]}"; do echo " - $m"; done + echo "" + echo "If you (or an AI tool) opened this PR without the template, click 'Edit' on the" + echo "PR description, paste the template, and fill it in. Editing the description" + echo "re-runs this check automatically. A complete PR is easy to review and" + echo "reproducible: that is part of the assignment." + exit 1 + fi + echo "All required PR sections present."