Skip to content

Latest commit

 

History

History
257 lines (188 loc) · 8.77 KB

File metadata and controls

257 lines (188 loc) · 8.77 KB

Generate Release Notes Action—for Developers

Get Started

Clone the repository and navigate to the project directory:

git clone https://github.com/AbsaOSS/generate-release-notes.git
cd generate-release-notes

Install the dependencies:

pip install -r requirements.txt
export PYTHONPATH=<your path>/generate-release-notes/src

Running Static Code Analysis

This project uses the Pylint tool for static code analysis. Pylint analyzes your code without actually running it. It checks for errors, enforces coding standards, looks for code smells, etc.

Pylint displays a global evaluation score for the code, rated out of a maximum score of 10.0. We aim to keep our code quality above 9.5.

Set Up Python Environment

python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

This command will also install a Pylint tool, since it is listed in the project requirements.

Run Pylint

Run Pylint on all files currently tracked by Git in the project.

pylint --ignore-paths='^tests/.*' $(git ls-files '*.py')

To run Pylint on a specific file, follow the pattern pylint <path_to_file>/<name_of_file>.py.

Example:

pylint release-notes-generator/generator.py

Run Black Tool Locally

This project uses the Black tool for code formatting. Black aims for consistency, generality, readability, and reducing git diffs. The coding style used can be viewed as a strict subset of PEP 8.

The project root file pyproject.toml defines the Black tool configuration. In this project, we are accepting a line length of 120 characters.

Follow these steps to format your code with Black locally:

Set Up Python Environment

From the terminal in the root of the project, run the following command:

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

This command will also install a Black tool, since it is listed in the project requirements.

Run Black

Run Black on all files currently tracked by Git in the project.

black $(git ls-files '*.py')

To run Black on a specific file, follow the pattern black <path_to_file>/<name_of_file>.py.

Example:

black release_notes_generator/generator.py

Expected Output

This is the console's expected output example after running the tool:

All done! ✨ 🍰 ✨
1 file reformatted.

Run mypy Tool Locally

This project uses the my[py] tool, a static type checker for Python.

Type checkers help ensure that you correctly use variables and functions in your code. With mypy, add type hints (PEP 484) to your Python programs, and mypy will warn you when you use those types incorrectly. my[py] configuration is in pyproject.toml file.

Follow these steps to format your code with my[py] locally:

Run my[py]

Run my[py] on all files in the project.

  mypy .

To run my[py] check on a specific file, follow the pattern mypy <path_to_file>/<name_of_file>.py --check-untyped-defs.

Example:

   mypy living_documentation_regime/living_documentation_generator.py

Running Unit Test

Unit tests are written using pytest. To run the tests, use the following command:

pytest tests/unit

This will execute all tests located in the tests/unit directory.

Running Integration Tests

The integration suite exercises the full pipeline from main.run() to final markdown output without reaching the GitHub API.

Offline tests (under tests/integration/) replace the GitHub API layer with mocks and run in CI on every PR — no token required, fully deterministic. Live tests (under tests/integration/live/) call the real GitHub API against the AbsaOSS/generate-release-notes repository. Run these manually to verify network-dependent behaviour such as BulkSubIssueCollector, or to confirm that API changes have not broken the integration. They are skipped in CI on fork PRs where the token is unavailable.

Design concept

Each test calls main.run() directly with INPUT_* environment variables. The GitHub API layer is replaced by mocks; DataMiner.mine_data() is patched to return a hand-crafted MinedData. All other pipeline components — FilterByRelease, DefaultRecordFactory, ReleaseNotesBuilder, CustomChapters, and ServiceChapters — execute as real code.

Key components

Component Location Role
Fixture factories conftest.py make_issue, make_pr, make_commit, make_repo, make_release — typed mocks with minimal required attributes
build_mined_data() helpers.py Assembles a MinedData from fixture objects for injection into the pipeline
capture_run() helpers.py Sets env vars, calls main.run(), parses the GitHub Actions output format back to a plain string
Golden snapshot fixtures/test_full_pipeline_snapshot.md Byte-for-byte reference output for T-INT-01

Run offline tests (no token needed)

Runs all integration tests except the live suite; safe to run locally and in CI.

pytest tests/integration/ --ignore=tests/integration/live -v

Regenerate golden snapshot

Re-runs the full-pipeline snapshot test and overwrites fixtures/test_full_pipeline_snapshot.md with the current output. Use this after intentional output changes to update the baseline.

WRITE_SNAPSHOTS=1 pytest tests/integration/test_snapshot.py::test_full_pipeline_snapshot

Live smoke test (requires GITHUB_TOKEN)

Queries the real GitHub API against AbsaOSS/generate-release-notes to verify BulkSubIssueCollector. Skipped in CI on fork PRs.

pytest tests/integration/live/ -v

Code Coverage

Code coverage is collected using the pytest-cov coverage tool. To run the tests and collect coverage information, use the following command:

pytest --cov=. -v tests/unit --cov-fail-under=80                      # Check coverage threshold
pytest --cov=. -v tests/unit --cov-fail-under=80 --cov-report=html    # Generate HTML report

This will execute all tests in the tests directory and generate a code coverage report.

See the coverage report on the path:

open htmlcov/index.html

Run Action Locally

Create run_locally.sh file and place it in the project root.

#!/bin/bash

# Set environment variables based on the action inputs
export INPUT_TAG_NAME="v0.2.0"

export INPUT_CHAPTERS='[
{ title: No entry 🚫, label: duplicate },
{ title: Breaking Changes 💥, label: breaking-change },
{ title: New Features 🎉, label: enhancement },
{ title: New Features 🎉, label: feature },
{ title: Bugfixes 🛠, label: bug },
{ title: Infrastructure ⚙️, label: infrastructure },
{ title: Silent-live 🤫, label: silent-live },
{ title: Documentation 📜, label: documentation }
]'
export INPUT_WARNINGS="true"
export INPUT_PUBLISHED_AT="true"
export INPUT_SKIP_RELEASE_NOTES_LABELS="ignore-in-release"
export INPUT_PRINT_EMPTY_CHAPTERS="true"
export INPUT_VERBOSE="true"

# CI in-built variables
export GITHUB_REPOSITORY="< owner >/< repo-name >"
export INPUT_GITHUB_TOKEN=$(printenv <your-env-token-var>)

PROJECT_ROOT="$(pwd)"
export PYTHONPATH="${PYTHONPATH}:${PROJECT_ROOT}"

# Debugging statements
echo "PYTHONPATH: ${PYTHONPATH}"
echo "Current working directory: ${PROJECT_ROOT}"

# Run the Python script
python3 ./<path-to-action-project-root>/main.py

Branch Naming Convention (PID:H-1)

All work branches MUST use an allowed prefix followed by a concise kebab-case descriptor (optional numeric ID): Allowed prefixes:

  • feature/ : new functionality & enhancements
  • fix/ : bug fixes / defect resolutions
  • docs/ : documentation-only updates
  • chore/ : maintenance, CI, dependency bumps, non-behavioral refactors Examples:
  • feature/add-hierarchy-support
  • fix/456-null-title-parsing
  • docs/update-readme-quickstart
  • chore/upgrade-pygithub Rules:
  • Prefix mandatory; rename non-compliant branches before PR (git branch -m feature/<new-name> etc.).
  • Descriptor lowercase kebab-case; hyphens only; avoid vague terms (update, changes).
  • Align scope: a docs-only PR MUST use docs/ prefix, not feature/. Verification Tip:
git rev-parse --abbrev-ref HEAD | grep -E '^(feature|fix|docs|chore)/' || echo 'Branch naming violation (expected allowed prefix)'

Future possible prefixes (not enforced yet): refactor/, perf/.