This repository has been archived on 2026-11-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
platform-ci/platform_ci/event_selection.py
forge-recoveryandClaude Sonnet 5.5 a36f17b857
KofTwentyTwo/ci-policy: ci / fork-guard (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / go-0 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / go-nix-1 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / gradle-2 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / gradle-3 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / java-docker-4 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / java-maven-5 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / manifests-6 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / nix-7 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / node-8 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / python-9 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / rust-10 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / rust-11 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / rust-12 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / source-config-13 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / source-config-14 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-0 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-1 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-2 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-3 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-4 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-5 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-6 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-7 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / not-enrolled (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / content-validate-0 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / standards-0 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / node-matrix-0 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / source-config-15 (pull_request) Blocked by required conditions
KofTwentyTwo/ci-policy: Shared source and config CI / verify (pull_request) Blocked by required conditions
KofTwentyTwo/ci-policy: Shared source and config CI / secrets (pull_request) Blocked by required conditions
KofTwentyTwo/ci-policy: Shared source and config CI / gate (pull_request) Waiting for needed jobs
KofTwentyTwo/ci-policy: ci / ci-result (pull_request) Waiting for needed jobs
KofTwentyTwo/ci-policy: native / fork-deny (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-macos-0 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-macos-1 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-macos-2 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-macos-3 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-windows-4 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-windows-5 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-windows-6 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-windows-7 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / dotnet-8 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / dotnet-9 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / dotnet-10 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / dotnet-11 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-12 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-13 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-14 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-15 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-16 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-17 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-18 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-19 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / native-result (pull_request) Canceled after 6s
feat(ci): advance shared pipeline capabilities
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 10:30:25 +00:00

79 lines
3.9 KiB
Python

"""One event-selection rule for components and images, shared by `prepare` and the trusted publisher so both pick the same targets.
UNTESTED: written while test execution was suspended.
The repository's own `release.channels` are its event vocabulary. A channel matches an event when the event's BRANCH (a push's branch, or a
pull request's head branch) matches its `push_branches`, or the event's pushed TAG matches its `push_tags`; the literal `pull_request` matches
every pull request. A channel that declares `trigger.manual: true` ALSO matches a manual run (`workflow_dispatch`, which carries no branch or tag), so a
channel with no push trigger is selected by a manual run and by nothing else. A component or image restricted by `only_on_channels` runs only when one of
those names matches, and one restricted by `not_on_channels` is skipped when any of them matches. Nothing here names a repository, an owner or a run.
"""
from collections.abc import Sequence
from dataclasses import dataclass
from fnmatch import fnmatchcase
from typing import Final
from platform_ci.configuration import ReleaseChannel, branch_matches
PULL_REQUEST: Final = "pull_request"
"""A reserved selection name (not a channel): matches every pull request event."""
PUSH: Final = "push"
MANUAL: Final = "workflow_dispatch"
"""The event name of a manual run (`github.event_name` of a `workflow_dispatch`, also seen by a callable run started by one): the only event a `manual` channel adds."""
@dataclass(frozen=True)
class EventFacts:
"""The authoritative event facts selection and fixed script variables use: event name, branch (push branch or pull request head), tag, revision."""
name: str
branch: str = ""
tag: str = ""
source_revision: str = ""
@property
def ref_type(self) -> str:
"""`tag` for the push of a tag, otherwise `branch` (a push branch or a pull request's head branch), the same words as `github.ref_type`."""
return "tag" if self.tag else "branch"
@property
def ref_name(self) -> str:
"""The short ref name a script may see: the pushed tag, else the push branch or pull request head branch."""
return self.tag or self.branch
def push_facts(branch: str, source_revision: str) -> EventFacts:
"""Return the facts of a push to a branch (what the trusted publisher releases from)."""
return EventFacts(PUSH, branch=branch, source_revision=source_revision)
def tag_facts(tag: str, source_revision: str) -> EventFacts:
"""Return the facts of a push of a tag (what the trusted publisher releases from for a tag-driven release kind)."""
return EventFacts(PUSH, tag=tag, source_revision=source_revision)
def channel_matches(channel: ReleaseChannel, facts: EventFacts) -> bool:
"""Return whether the event is one the channel's triggers select: a manual run for a `manual` channel, or the event's branch or tag."""
if channel.manual and facts.name == MANUAL:
return True
if facts.branch and branch_matches(channel.push_branches, facts.branch):
return True
return bool(facts.tag) and any(fnmatchcase(facts.tag, pattern) for pattern in channel.push_tags)
def matching_channel_names(channels: Sequence[ReleaseChannel], facts: EventFacts) -> set[str]:
"""Return the names of the channels the event matches, plus `pull_request` for a pull request."""
names = {channel.name for channel in channels if channel_matches(channel, facts)}
return names | {PULL_REQUEST} if facts.name == PULL_REQUEST else names
def selected(only_on: Sequence[str], not_on: Sequence[str], channels: Sequence[ReleaseChannel], facts: EventFacts) -> bool:
"""Return whether something restricted by `only_on` / `not_on` applies to this event; with neither it always does."""
if not only_on and not not_on:
return True
matching = matching_channel_names(channels, facts)
if only_on and not matching & set(only_on):
return False
return not matching & set(not_on)