Skip to content

Latest commit

 

History

91 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitHub Templates Repository

Welcome to our GitHub Templates repository! 🚀 This repository serves as a centralized location for various templates used across our GitHub repositories. Whether you're looking for issue templates, pull request templates, or any other standardized documents, you'll find them all here.

Templates Available

Currently, we provide the following templates:

  • Issue Templates: Standardized templates to help you report issues effectively.

Reusable workflows

Every repository calls these rather than copying the steps, so a fix lands once.

Workflow Purpose
ci_dotnet.yml Restore, build, and test a .NET solution. Accepts a caller-supplied checkout-ref for Dependabot/Renovate PRs; carries no id-token: write and no Azure sign-in capability by design
ci_dotnet_azure.yml Same, plus Azure OIDC sign-in for fixtures that resolve @Microsoft.KeyVault(...) references. Never accepts checkout-ref -- for a repository's trusted (non-Dependabot) PR lane only
ci_react_build.yml, ci_react_unit_tests.yml, ci_react_publish.yml, ci_react_storybook_tests.yml The React library pipeline
ci_wcag_check.yml Accessibility check that blocks merge in React Components
spa_build.yml, spa_deploy.yml Build and deploy a single-page app
release_nuget_packages.yml Publish NuGet packages
create_maintenance_branch.yml Cut a maintenance branch
azure-storage-sync.yml Sync blob storage between rings
pr_compliance.yml Deterministic pull request checks — the facts
pr_code_review.yml The EasyLife 365 review standard, run on the pull request — the judgement
pr_agent_review.yml Verifies a Claude review exists for the pull request — the gate

Versioning

Every caller today references these workflows at @main — there is no version tag yet to pin against, and this repository has no history of ever cutting one. That is a real gap: @main means every caller adopts a change to a reusable workflow the moment it merges, with no way to stay on a known-good version while a fix is verified elsewhere first.

The convention: semantic version tags on the whole repository, one version line covering every reusable workflow together rather than per-file versions, since a caller pins a commit of this repository, not a single file in isolation.

  • v1.2.3 is an exact tag. It never moves once published — pin it for a frozen, reproducible reference.
  • v1 is a floating tag, moved to the newest v1.x.x release the moment it publishes. Pin it to always get the latest fix in that major line without a manual bump — the same convention actions/checkout@v4 and every other third-party Action use.
  • A major bump means a breaking change to an existing input, output, or default for an existing caller (removing an input, changing what a default does, renaming a secret). A minor bump adds something new and backward compatible (a new optional input, a new workflow file). A patch bump fixes a bug in existing behaviour without changing the interface — #107's Test-step fix would have been a patch, had this convention existed when it merged.

Cutting a release: run the Release workflow (workflow_dispatch) with the version number (1.2.3, the v is added for you). Use dry_run: true first to validate without publishing. The actual tag/release/major-tag-move work is delegated to EasyLife365/get-version-action's create-release action rather than hand-rolled here -- this file used to duplicate that logic in bash, which is exactly the kind of two-copies-that-drift this readme's own reusable-workflows philosophy exists to avoid (see the table above: "Every repository calls these rather than copying the steps, so a fix lands once" -- the same principle, one repository up). Release notes are auto-generated from merged PR titles since the last tag — which is why a PR title must carry its issue keyword (see the Pull request review section below): that keyword is what "What's Changed" is built from.

Pinning by tag is opt-in, not required yet. No caller has been migrated off @main as part of building this convention — that is a separate, later pass, once the convention itself has a real release behind it to prove out. pr_agent_review.yml in particular has a standing reason to stay unpinned regardless (see "The caller shape" below: pinning it would change whether secrets: inherit is safe on the caller side).

Pull request review

Review is three layers, and the split is deliberate.

pr_compliance.yml settles what a script can settle: the issue keyword, newly added credential files, react-table >= 9, mixed EL.* package versions, a project missing from the solution, test-folder placement, branch naming, and a notice on restricted paths. No model, no token spend, no false positives — so this one is safe to make a required check.

pr_code_review.yml runs the Code Reviewer standard from .github-private and posts inline comments. It is advisory: it never approves, never counts toward a required human approval, and must not be a required check — an LLM finding is an opinion worth reading, and a flaky merge gate teaches people to ignore the checks that are not flaky.

pr_agent_review.yml is the third layer and behaves unlike the other two. It does not read the diff and forms no opinion. It answers one question: did a Claude review happen on this pull request? The approver of record runs /el-review in their own session; that skill posts the findings and records a marker naming the commit it reviewed, and this check looks for the marker. One review per pull request is enough: a push after the review does not turn the check red. When the reviewed commit is not the head, the status says so (Reviewed by @user at fd0066f, 2 commits since), so an approver can see how far the code has moved past the review and re-run /el-review if that matters to them. A small first commit reviewed and a large change pushed afterwards stays green; that trade-off is accepted (see .github#135).

Because it is a fact rather than a judgement, it is safe to require. It enforces the agent half of the approval rule:

One human approval plus a passing agent review on every pull request.

/el-review is not /code-review. Anthropic ships a built-in skill called code-review. It prints findings in the terminal, posts nothing to the pull request unless given --comment, and never writes the easylife-review marker — so it cannot clear this check. A reviewer who runs it sees a full set of findings and reasonably believes they have reviewed the pull request, while the pull request itself receives nothing and stays red. That is why ours carries the el- prefix rather than sitting next to it as review.

Who can satisfy it. The marker is accepted only from a review (not a plain comment) by someone with OWNER, MEMBER or COLLABORATOR standing, or with write access to the repository. The second route is there because the check reads with github.token, which sees a private org member as CONTRIBUTOR; the reviewer's repository permission does not depend on whether their membership is public. A pull request author may satisfy it on their own pull request — running /el-review before asking anyone to look is a good habit and banning it would only discourage it — but the status names who posted it, so an approver sees a self-review and can re-run it. The human approval is a separate person regardless; GitHub enforces that.

This is not tamper-proof, and should not be described as such. Anyone with push access can post the agent-review status directly with their own token — commit statuses carry no per-context write protection. The ceiling is "who can push". What the marker rules buy is that the lazy path is no longer the wrong path: clearing the gate without a review takes deliberate effort rather than a copied line.

Read the status, not the job. The agent-review-check job goes green whenever it posted a status; the answer is in the agent-review status itself. A check run is never retracted, so once a review lands the review-triggered run adds a second check run of the same name — you will see two agent-review-check / Agent review entries on a pull request that went red then green. That is the lifecycle showing its history, not a failure. The job only fails when it could not post a status at all.

A green agent-review is not an agent sign-off. It means a review exists for this commit, not that the review was favourable. The findings are in the review; the human approval is the gate.

Both compliance and the agent check are wired per repository, and every compliance check is individually switchable, because the estate genuinely differs — Collaboration does not use the feature-folder hierarchy, four repositories have no .sln, and EasyMeet 365 is on different package versions on purpose.

The caller shape

Copy this. Every line that looks fussy is load-bearing, and the notes below say why.

name: PR Review

on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review, edited]
  pull_request_review:
    types: [submitted]

concurrency:
  group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  compliance-gate:
    if: github.event_name == 'pull_request'
    permissions:
      contents: read
    uses: EasyLife365/.github/.github/workflows/pr_compliance.yml@main
    with:
      solution-file: EL.Core.sln
    secrets: inherit

  agent-review-check:
    permissions:
      contents: read
      pull-requests: read
      statuses: write
    uses: EasyLife365/.github/.github/workflows/pr_agent_review.yml@main

  review:
    # A called workflow cannot hold more than the calling job grants, so the review job
    # needs these even though the reusable workflow declares them. `pull-requests: write`
    # is permission to comment, not to approve.
    permissions:
      contents: read
      pull-requests: write
      issues: read
      id-token: write
    uses: EasyLife365/.github/.github/workflows/pr_code_review.yml@main
    secrets: inherit

edited is in the pull_request types on purpose. pr-compliance.mjs reads the pull request body, and its issue-keyword check is the one that fails most often. Without edited, that failure cannot be cleared by the obvious action: editing the body fires no event, and re-running the job does not help either — a re-run replays the stored event payload, so it still sees the old body. What is left is a new commit or close-and-reopen, both worse than one extra run.

pull_request_review: [submitted] is not optional. The agent review is posted after a pull_request-triggered run has already finished, and posting a review does not re-fire pull_request. A caller that triggers only on pull_request fails agent-review once and never re-runs it, however many reviews follow — the pull request is then unmergeable until someone re-runs the workflow by hand.

No job id may equal a required check name. A caller job that can be skipped reports a check run under its bare job id, and GitHub counts a skipped check as passing. compliance-gate skips on every review-triggered run, so naming it compliance would let anyone with read access submit a review and shadow a failing compliance / Compliance with a passing bare compliance. Hence compliance-gate and agent-review-check, not compliance and agent-review. The required contexts stay compliance / Compliance and the agent-review commit status.

The guard is written in the positive form. if: github.event_name == 'pull_request' rather than != 'pull_request_review', so a trigger added later has to opt in deliberately instead of silently inheriting a payload pr-compliance.mjs cannot parse.

Dismissing a review takes it back, but only at the next run. agent-review ignores dismissed reviews. Because a later push no longer retires a review, a caller that wants a dismissal to turn the status red straight away adds dismissed to its pull_request_review types; without it the status is recomputed on the next push or review.

The concurrency group is keyed by event. The two event types do not run the same job set — a review run skips compliance — so sharing a group with cancel-in-progress lets a review submission cancel an in-flight push run's compliance job and never replace it, leaving the required check cancelled. The run_id fallback degrades safe: an absent pull request number gives a group unique per run rather than a shared ref key that would cancel other pull requests.

agent-review-check takes no secrets: inherit. pr_agent_review.yml declares no secrets and runs entirely on github.token. Callers reference it unpinned, so inheriting would hand a step added there later every one of your repository's secrets with no caller-side change ever being reviewed.

merge_group is deliberately absent. Neither reusable workflow can serve a merge group today: pr-compliance.mjs exits when event.pull_request is absent, and pr_agent_review.yml reads the pull request number from the same place. Adding the trigger ahead of that support does not make a queue ready — it guarantees every queued pull request fails one check and waits forever on the other. Teach both scripts to resolve the pull request from github.event.merge_group.head_ref (a full ref, refs/heads/gh-readonly-queue/main/pr-123-<sha>) first.

Fork pull requests are not supported. On a fork pull_request the token is read-only regardless of the permissions: block, so the status POST fails and no status is posted — leaving a required agent-review at "Expected" indefinitely. Every repository in the estate is branch-PR-only today; do not make agent-review required anywhere that takes fork contributions without fixing this first.

Prerequisites, the rules the review applies, and the rollout order are documented in docs/agents/pr-review.md.

Scripts

Path Purpose
scripts/check-wcag.mjs Accessibility rules for the WCAG check
scripts/pr-compliance.mjs The deterministic pull request checks run by pr_compliance.yml
scripts/pr-agent-review.mjs The agent-review check run by pr_agent_review.yml

About

Repository used to centralize issue templates

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages