Bitwarden Designer
Bitwarden Product Analyst
Bitwarden Tech Lead
Bitwarden Testing Tools
Claude Config Validator · Reviewing…
Claude Retrospective
65 skills · 321 min
Bitwarden Dev Ops Engineer
Skill 30 of 65
Reference for Bitwarden GitHub Actions naming conventions that the workflow linter (bwwl) does not enforce.
5 minutes · 1,005 words · 7 sections
Install
npx skills add bitwarden/ai-plugins --skill auditing-workflow-conventionsnpx skills add bitwarden/ai-plugins/plugin marketplace add bitwarden/ai-pluginsThe first command installs just this skill, by the name in its SKILL.md; the second installs the whole repository.
This skill covers only what bwwl cannot check. For anything the linter enforces, invoke Skill(bitwarden-devops-engineer:bitwarden-workflow-linter-rules) — that skill is the source of truth for all bwwl rules, including their triggers and fix procedures. Do not report a finding here that duplicates a linter rule.
| Naming category | Owner |
|---|---|
| Job IDs | This skill |
| Step name casing | This skill |
| Workflow file names | This skill |
Workflow and job display name: | bitwarden-workflow-linter-rules — name_capitalized, name_exists |
| Outputs | bitwarden-workflow-linter-rules — underscore_outputs |
| Job-level env vars | bitwarden-workflow-linter-rules — job_environment_prefix |
| Inputs, bash variables, artifact names | No standard. Do not invent one — flag the gap instead. |
name_capitalized checks only that the first character is capitalized. Get Package Version passes the linter and still deviates from the Sentence case standard below. The two are complementary.
These three IDs are defined by this skill, not by bwwl. Label them as convention findings, never as linter findings.
job-id-kebab-casejobs:.kebab-case.build, test, lint, publish, upload, build-artifacts, deploy-service, check-permissions, calculate-version.bump_version, cut_branch, deployService, DeployService, BUILD_ARTIFACTS.snake_case, camelCase, PascalCase, or UPPER_SNAKE. Single-word IDs are compliant and are never a finding.A job ID is an identifier, not a label. Before proposing a rename, resolve every reference:
needs: in the same file, in both scalar and list form.${{ needs.<job-id>.* }} expressions anywhere in the file.jobs.<job-id>.outputs at the workflow level of a reusable workflow.Check-run names derive from a job’s name:, not its ID, so a job-ID rename does not affect required status checks — unless the job has no name:, in which case the ID becomes the check name and a rename can break a ruleset that requires it. name_exists already flags a job with no name:; if you encounter one, fix that first and rename second.
step-name-sentence-casename: under steps:.Azure, Docker, Node, .NET, SDK, RC, MSSQL.Check out repo, Set up .NET, Print environment, Log in to Azure, Generate Docker image tag, Install Node dependencies, Run tests, Push changes, Upload SDK artifacts.Delete Release Branch, Get Package Version, Build & Package Binaries, Upload SDK Artifacts, Dependency install.Step names are display-only — they are not addressable from expressions, since steps.<id> resolves the step’s id:. Changing one is safe and needs no reference sweep. This is the only standard here an agent may apply directly during an edit.
workflow-file-naming.github/workflows/.kebab-case.yml, with a _ prefix if and only if the workflow is exclusively reusable. The extension is always .yml, never .yaml. The prefix and the casing are independent — _deploy_service.yml is correctly prefixed and incorrectly cased; the compliant form is _deploy-service.yml.build-app.yml, scan-dependencies.yml, _version.yml, _deploy-service.yml.build_only.yml, API_tests.yml, Integration_Tests.yml, deploy-service.yaml, _deploy_service.yml.kebab-case, the extension is .yaml, an exclusively reusable workflow lacks the _ prefix, or a _-prefixed file is not exclusively reusable.Exclusively reusable means the on: block declares nothing outside workflow_call and workflow_dispatch. workflow_dispatch is a manual testing and operations escape hatch, not a standalone entry point, so it does not disqualify the prefix.
Any other trigger — push, pull_request, pull_request_target, schedule, release, workflow_run, repository_dispatch — makes the workflow dual-purpose: it both runs on its own and is callable by others. Dual-purpose workflows take no prefix. This is a deliberate and common design, not a deviation. Presence of workflow_call alone never justifies a prefix finding; check the full trigger set first.
on: block | Prefix |
|---|---|
workflow_call | Required |
workflow_call + workflow_dispatch | Required |
workflow_call + any auto-trigger | None — dual-purpose |
No workflow_call | None |
Renaming a workflow file is destructive. The filename is the workflow’s public identifier — it addresses the workflow from outside the repo, and every external reference breaks silently on rename. Never rename one as part of an audit or an unrelated edit. Report it and let the repo owner schedule it.
If a rename is explicitly requested, establish the known reference set first, then use git mv:
uses: ./.github/workflows/<file> and any local script that names it.gh search code "<file>" --owner bitwarden. Catches uses: bitwarden/<repo>/.github/workflows/<file>@<ref> in other repos plus any script or tooling that names the file. A local grep will not find these.This establishes a floor, not a ceiling. Nothing outside the org’s indexed code is discoverable: automation in other systems, runbook and documentation links, and anything invoking the workflow by filename through the dispatch API. Report what the two searches found and state plainly that the set may be incomplete — the residual unknown is exactly why the rename belongs to the repo owner and not to an audit.
Run history is keyed to the file path and always detaches on rename. Prior runs remain but no longer group under the renamed workflow. This is unavoidable — surface it, do not try to preserve it.
Preferred wording, not a standard. Consistent phrasing makes steps greppable across repos, but a step name outside this table is never a finding — most step names are legitimately unique to their workflow.
| Action | Canonical form | Also seen |
|---|---|---|
| Check out the repository | Check out repo | Checkout repo, Checkout code, Checkout Branch, Check out repository, Checkout |
| Log in to Azure | Log in to Azure | Login to Azure, Azure Login |
| Log out from Azure | Log out from Azure | — |
| Install a toolchain | Set up {tool} — two words, matching actions/setup-* | Setup {tool} |
| Retrieve secrets from AKV | Retrieve secrets | Get secrets, Setup secrets |
| Print the environment | Print environment | Print Environment |
When a step name both deviates from Sentence case and appears in this table (Azure Login), the casing is the finding and the canonical form is the suggested fix.
allowed-tools is read-only — enough to inspect workflows and run the org-wide reference sweep, nothing more.name_capitalized, underscore_outputs, or job_environment_prefix, the finding belongs to the linter. See the ownership table.Reference for Bitwarden GitHub Actions naming conventions that the workflow linter (bwwl) does not enforce. Covers three standards — job IDs (kebab-case), step names (Sentence case imperative), and workflow file names (kebab-case.yml, `_` prefix for reusable) — plus an advisory canonical step-name glossary and reference-sweep procedures for job ID and filename renames. Use when auditing or authoring workflows and questions like "what casing should job IDs use", "should this reusable workflow be build.yml or _build.yml", or "review these workflows for naming consistency" come up. Read alongside bitwarden-workflow-linter-rules, which is the source of truth for linted rules; this skill covers only the gaps.
The verbatim description from this skill’s front matter — the string an agent matches on to decide whether to load it.
ReadGlobGrepSkillBash(gh search code:*)plugins/bitwarden-devops-engineer/skills/auditing-workflow-conventions/SKILL.mdmain, last pushed 23 September 2026.SKILL.md, not by matching a directory convention. 13 distinct layouts observed: plugins/bitwarden-atlassian-tools/skills/*/SKILL.md, plugins/bitwarden-code-review/skills/*/SKILL.md, plugins/bitwarden-delivery-tools/skills/*/SKILL.md, plugins/bitwarden-design-tools/skills/*/SKILL.md, plugins/bitwarden-designer/skills/*/SKILL.md, plugins/bitwarden-devops-engineer/skills/*/SKILL.md, plugins/bitwarden-product-analyst/skills/*/SKILL.md, plugins/bitwarden-security-engineer/skills/*/SKILL.md, plugins/bitwarden-shepherd/skills/*/SKILL.md, plugins/bitwarden-tech-lead/skills/*/SKILL.md, plugins/bitwarden-testing-tools/skills/*/SKILL.md, plugins/claude-config-validator/skills/*/SKILL.md, plugins/claude-retrospective/skills/*/SKILL.md..claude-plugin/marketplace.json by Bitwarden, declaring 16 plugins. It is read for editorial metadata only — never as the skill index, which is always the repository tree./bitwarden/ai-plugins.md, and each skill at its own .md URL.