CONTRIBUTING
How to contribute to GDPR-IAB-TCFv2?
DESCRIPTION
Patches are welcome!
They must be built against the devel branch, then submitted as pull requests at GitHub.
The documentation is written using the POD format. Use the perldoc tool to render it in a terminal:
perldoc CONTRIBUTING.pod
PATCHING, STEP BY STEP
- 1. Get the source
-
git clone --origin upstream git://github.com/peczenyj/GDPR-IAB-TCFv2.git cd GDPR-IAB-TCFv2 git checkout devel - 2. Install build dependencies
-
Not required for doc patches.
curl -L https://cpanmin.us | perl - --installdeps --with-develop . - 3. Make your fix/feature
-
git checkout -b <my-patch> devel # edit files and add modification # Run the testsuite prove -v git commit -s -m '<<some nice message>>' - 4. Setup a fork
- 4.1. Fork the project on GitHub
- 4.2. Link your local repo to your fork (just once)
-
(You are using
GDPR-IAB-TCFv2isn't it?)git remote add github <github-user>.github.com:<github-user>/GDPR-IAB-TCFv2.git - 5. Submit your work
- 5.1 Push!
-
git push github <my-patch> - 5.2 Submit a pull request on GitHub
- 6. Loop
-
Redo from step 3.
RELEASING A NEW VERSION
This project follows the Git Flow branching model: feat/* and fix/* branches merge into devel; release/* branches cut from devel and merge into both main and devel; hotfix/* branches cut from main and merge into both. Tags live on main.
The recommended path uses the git-flow CLI (git-flow-avh) to drive the ceremony. Plain git works too — both variants are shown side-by-side at each step so you can pick one.
The release pipeline itself is fully automated by .github/workflows/release.yml: pushing any v* tag triggers a build, a PAUSE upload, and a GitHub Release with the tarball attached. You only need to drive the local prep and the merge/tag.
Prerequisites (one-time)
- 1. Install release tooling
-
# POD → Markdown converter (regenerates README.md) cpanm Pod::Markdown # or: apt install libpod-markdown-perl # Conventional-Commits changelog generator cargo install git-cliff # or: brew install git-cliff # git-flow CLI (optional but recommended) apt install git-flow # or: brew install git-flow-avh - 2. Initialize git-flow once (skip if you prefer plain git)
-
git flow init -dWhen prompted, accept the project's existing layout:
production branch =
mainnext-release branch =
develfeature prefix =
feat/release prefix =
release/hotfix prefix =
hotfix/
The
-dflag uses defaults where they match; you'll only be prompted for the values that differ. - 3. Configure CPAN credentials (repo admin, one-time)
-
In GitHub, go to Settings → Secrets and variables → Actions and add:
PAUSE_USER— your PAUSE usernamePAUSE_PASSWORD— your PAUSE password
If these secrets are missing, the GitHub Release step still runs but the PAUSE upload step is skipped.
Versioning convention
$VERSION uses the 3-digit 0.XYZ form. Bump the last two digits in steps of 10 for normal releases (e.g. 0.350 → 0.360) and by 1 for pure bug-fix follow-ups (e.g. 0.350 → 0.351). The git tag prepends v (e.g. v0.360); the $VERSION string in the .pm does not.
Step-by-step release
- 1. Sync
develand confirm what's queued -
git checkout devel git pull --ff-only git log --oneline $(git describe --tags --abbrev=0)..HEADThe log shows everything that will land in the new release. If something that should be in this release is missing, merge its PR before continuing.
- 2. Open a release branch
-
git-flow:
git flow release start 0.360vanilla git:
git checkout -b release/0.360 devel - 3. Bump
$VERSION -
$EDITOR lib/GDPR/IAB/TCFv2.pm # Edit: our $VERSION = "0.360";Makefile.PL reads the version from this file via
VERSION_FROM; no other file needs editing. - 4. Regenerate the changelog
-
git cliff --tag v0.360 -o CHANGELOG.mdcliff.tomlis preconfigured for Conventional Commits and groups byfeat:/fix:/docs:/perf:/refactor:/Other;style:/test:/chore:are skipped.Sanity-check the output — git-cliff slurps full commit message bodies, so stray lines like
# Conflicts:from merge commits can leak into the changelog. Strip them by hand if present. - 5. Regenerate the README
-
pod2markdown lib/GDPR/IAB/TCFv2.pm > README.mdOnly the main module's POD ships in
README.md; submodule POD is served via MetaCPAN. - 6. Build and verify locally
-
perl Makefile.PL make make test # runs t/ prove -lr xt # runs perlcritic + perltidy make manifest # updates MANIFEST if test files were added make dist # produces GDPR-IAB-TCFv2-0.360.tar.gzOpen the tarball and confirm only intended files ship (no .bak, no docs/, no AGENTS.md, no MYMETA.*).
MANIFEST.SKIPalready excludes those, but a quick eyeball is cheap insurance. - 7. Commit the release prep
-
git add lib/GDPR/IAB/TCFv2.pm CHANGELOG.md README.md # Also `git add MANIFEST` if `make manifest` changed it git commit -m "chore: prepare for v0.360 release"One commit. Do not tag yet — the tag is created in step 8.
- 8. Finish the release
-
git-flow (recommended — automates the merges and tag):
git flow release finish 0.360 # Prompts for the tag message; use something like: # "Release v0.360 — <one-line theme>" git push origin main git push origin devel git push origin v0.360 # ← triggers release.ymlgit flow release finishmergesrelease/0.360into main, tags it asv0.360, merges back into devel (so the version bump and changelog land there too), and deletes the localrelease/0.360branch.You must push all three refs. The release workflow only fires on the tag push, but the tag must be reachable from
mainfor the workflow to check out the right tree.vanilla git (more steps, gives reviewable PRs):
# 1. PR release/0.360 → devel git push -u origin release/0.360 gh pr create --base devel \ --title "chore: prepare for v0.360 release" \ --body "Version bump, README regen, changelog refresh." # Review and merge on GitHub. # 2. PR devel → main gh pr create --base main --head devel \ --title "Release v0.360" # Review and merge on GitHub. # 3. Tag main and push git checkout main git pull --ff-only git tag -a v0.360 -m "Release v0.360 — <one-line summary>" git push origin v0.360 # ← triggers release.yml - 9. Watch the release workflow
-
gh run watch -R peczenyj/GDPR-IAB-TCFv2 # or gh run list -R peczenyj/GDPR-IAB-TCFv2 --workflow release.yml --limit 1The workflow does:
perl Makefile.PL && make manifest && make dist— produces the tarballcpan-upload -u $PAUSE_USER -p $PAUSE_PASSWORD ...— uploads to PAUSE (skipped silently ifPAUSE_USERis empty)softprops/action-gh-release@v2— creates the GitHub Release with the tarball attached and auto-generated notes
If the PAUSE step fails, the GitHub Release still gets created. You can then re-upload manually via https://pause.perl.org/ without re-running the workflow.
- 10. Post-release sanity
-
# Confirm the GitHub Release gh release view v0.360 -R peczenyj/GDPR-IAB-TCFv2 # Wait ~30 min for PAUSE → MetaCPAN propagation, then: curl -s https://fastapi.metacpan.org/v1/release/GDPR-IAB-TCFv2 \ | jq .version # Should report "0.360"The docker image (
peczenyj/gdpr-iab-tcfv2:0.360and:latest) is published by .github/workflows/docker.yml on the samev*tag push.
Pre-release review (and why we don't use draft GitHub Releases)
GitHub supports draft releases that you can review before publishing. For most projects this is a useful pre-publish review gate. For this project it is not, and the doc deliberately omits the pattern. Two reasons:
PAUSE upload is irreversible. Once release.yml uploads GDPR-IAB-TCFv2-0.360.tar.gz to PAUSE, the version number is burned forever — you can delete the file but can't re-upload a new tarball under the same version. So a "review the GitHub Release before it goes out" gate doesn't actually protect the thing that matters (the CPAN-distributed artifact); it only protects the rendered release-notes page.
The current release.yml hard-codes
draft: false. If you created a draft release withgh release create --draftand then pushed the tag, the workflow'ssoftprops/action-gh-release@v2step would update the release and flipdraftto false — closing the review window the moment the workflow finishes (~3 minutes). Conversely, if you letgh release create --target main --draftcreate the tag via the REST API instead of pushing it viagit, release.yml would not fire at all (push events from API-created tags don't trigger workflows), and your tarball would never reach PAUSE.
The review gate that actually buys you something is the release-prep PR in the vanilla-git path of step 8: opening release/0.360 → devel and devel → main as PRs lets a reviewer (or future-you) catch a typo in the changelog, an off-by-one in $VERSION, or a stale README before the merge that triggers the unstoppable downstream automation. Use that path when you want pre-release review.
If you ever do want the draft-release pattern to work properly, it needs a workflow tweak: add release: { types: [published] } to release.yml's on: triggers, and remove draft: false from the softprops step. The doc does not include that variant today.
Hotfix releases
For an urgent fix that has to skip devel and ship straight from main:
git-flow:
git flow hotfix start 0.351
# Make the fix, bump $VERSION, regenerate CHANGELOG and README, commit
git flow hotfix finish 0.351
git push origin main devel v0.351
vanilla git:
git checkout -b hotfix/0.351 main
# Make the fix, bump $VERSION, regenerate CHANGELOG and README
git add lib/GDPR/IAB/TCFv2.pm CHANGELOG.md README.md
git commit -m "fix: <description> (v0.351)"
git push -u origin hotfix/0.351
# PR hotfix/0.351 → main
gh pr create --base main --title "Hotfix v0.351 — <description>"
# Merge.
# Merge main back into devel so the fix doesn't get lost
git checkout devel
git pull --ff-only
git merge --no-ff main -m "Merge hotfix v0.351 back into devel"
git push
# Tag main and push
git checkout main && git pull --ff-only
git tag -a v0.351 -m "Hotfix v0.351 — <description>"
git push origin v0.351