ワンクリックで
qtpass-linting
// QtPass CI/CD workflow - run GitHub Actions locally with act, linters, formatters
// QtPass CI/CD workflow - run GitHub Actions locally with act, linters, formatters
QtPass localization workflow - translation files, updating, adding languages
QtPass localization audit - structural checks on .ts files (placeholders, HTML balance, mnemonics, mixed-script artifacts)
QtPass GitHub interaction - PRs, issues, branches, merging
Bug fixing workflow for QtPass - find, fix, test, PR
Documentation guide for QtPass - README, FAQ, localization
Release workflow for QtPass - versioning, builds, publishing
| name | qtpass-linting |
| description | QtPass CI/CD workflow - run GitHub Actions locally with act, linters, formatters |
| license | GPL-3.0-or-later |
| metadata | {"audience":"developers","workflow":"linting"} |
The lint workflow uses super-linter/super-linter@v8.6.0 which resolves to image ghcr.io/super-linter/super-linter:v8.6.0. Critical quirks learned the hard way:
LINTER_RULES_PATH defaults to .github/linters/ — every per-linter config file that super-linter explicitly passes via --config <path> lives there, not at the repository root.
| Linter | Config file |
|---|---|
| zizmor | .github/linters/zizmor.yaml |
Other linters auto-discover their own dotfiles like .codespellrc, .clang-format, .commitlintrc.js, .jshintrc, .jshintignore, .yaml-lint.yml, .codecov.yml from the repository root via the linter's own conventions — those don't go under .github/linters/.
super-linter.env rulesKEY=value only — no comments, no empty lines, alphabetical (dotenv-linter UnorderedKey rule). The workflow does cat .github/super-linter.env >> $GITHUB_ENV and $GITHUB_ENV rejects everything else.cat step), not in the env file.GITHUB_* env vars set via $GITHUB_ENV don't propagate to docker-based actions like super-linter. So you cannot override e.g. GITHUB_ACTIONS_ZIZMOR_CONFIG_FILE this way — put the config at the default-discovered location instead.act is unreliable for super-linter — the floating :v7/:v8 tags drift, and act's mock GitHub event JSON lacks fields that v8 super-linter needs (forced for push events). The reliable reproduction is the exact CI image via Docker:
# Run a specific linter (e.g. zizmor) the way CI does
docker run --rm -v "$PWD:/work" -w /work \
--entrypoint zizmor ghcr.io/super-linter/super-linter:v8.6.0 \
--config .github/linters/zizmor.yaml .github/workflows/
# Or clang-format check
docker run --rm -v "$PWD:/work" -w /work \
--entrypoint clang-format ghcr.io/super-linter/super-linter:v8.6.0 \
--style=file --dry-run --Werror path/to/file.cpp
Or install native binaries: cargo install zizmor, distro packages for clang-format/yamllint/codespell.
hash-pin; we override to ref-pin in the config (version tags + dependabot cooldown)..commitlintrc.js from the repository root.esversion: 11 in .jshintrc.act works well for most workflows but the super-linter image has version drift and event-mock issues — see "Reproducing CI locally" above for the reliable alternative.
Always run local CI before pushing PRs. Use act for most workflows; for super-linter workflows, prefer the Docker-based alternative described above (version drift and event-mock issues make act unreliable there).
# 1. Make your changes
git add .
# 2. Run linter locally (this is the pattern)
act push -W .github/workflows/linter.yml -j build
# 3. Fix any issues
# 4. Push only when act passes
| Task | Command |
|---|---|
| Run linter | act push -W .github/workflows/linter.yml |
| Run linter (specific job) | act push -W .github/workflows/linter.yml -j build |
| Run build & tests | act push -W .github/workflows/ccpp.yml |
| Run docs | act push -W .github/workflows/docs.yml |
| Run reuse check | act push -W .github/workflows/reuse.yml |
Runs super-linter with many linters:
# Run linter locally
act push -W .github/workflows/linter.yml -j build
QtPass build with Qt5/Qt6 matrix, runs unit tests, generates coverage:
# Run build workflow
act push -W .github/workflows/ccpp.yml
Tests against:
Note: Qt installation may fail in act due to environment limitations. Real CI handles this.
# Run docs workflow
act push -W .github/workflows/docs.yml
Check license headers and REUSE compliance:
# Run reuse check
act push -W .github/workflows/reuse.yml
The CI enforces zero Doxygen warnings via docs.yml. WARN_AS_ERROR = FAIL_ON_WARNINGS in Doxyfile causes the step to fail on any undocumented public symbol.
doxygen Doxyfile
# No warnings = CI will pass (progress output is normal with QUIET = NO)
| Setting | Value | Purpose |
|---|---|---|
FILE_PATTERNS | *.cpp *.h *.md | Includes cpp, header, and Markdown files |
EXTRACT_ALL | NO | Required for WARN_NO_PARAMDOC to work |
WARN_NO_PARAMDOC | YES | Requires @param/@return on all public symbols |
WARN_AS_ERROR | FAIL_ON_WARNINGS | Fails CI on any warning |
QUIET | NO | Progress output shown (not an error) |
Use /** */ blocks with @brief, @param, @return:
/**
* @brief Brief one-line description.
* @param name Description of parameter.
* @return Description of return value.
*/
void foo(int) — name all parameters: void foo(int count)/** ... */ not immediately preceding its declaration is misattributed. Move the block directly above the declaration.@return: Enforced with current settings (WARN_NO_PARAMDOC = YES) — include @return for non-void functions@param docs@xyz typos: Doxygen treats unknown @word as commands — use @brief Like not @likeCreate a temporary Doxyfile override to enable XML for coverxygen (base Doxyfile may not have XML enabled):
# Generate XML docs (required for coverxygen)
cp Doxyfile Doxyfile.xml
echo "GENERATE_XML = YES" >> Doxyfile.xml
echo "XML_OUTPUT = xml" >> Doxyfile.xml
doxygen Doxyfile.xml
# Install and run coverxygen
pip install coverxygen
python -m coverxygen --xml-dir xml/ --src-dir . --output coverage.info
Detects API keys, tokens, passwords in code.
# Scan for secrets
gitleaks detect
Common Fixes:
# Check formatting
clang-format --style=file --dry-run src/main.cpp
# Apply formatting
clang-format --style=file -i src/main.cpp
Formats shell scripts in scripts/ folder. Uses LLVM style (matches clang-format).
Installation:
# macOS
brew install shfmt
# Go
go install mvdan.cc/sh/v3/cmd/shfmt@latest
# Check formatting
shfmt -d scripts/*.sh
# Apply formatting
shfmt -w scripts/*.sh
Clangd provides deep static analysis via LSP. Requires compile_commands.json:
# Generate compile_commands.json (required for Qt headers)
./scripts/generate-compile-commands.sh
# Check a specific file for issues
clangd --check=src/gpgkeystate.cpp
Common diagnostics:
[performance-unnecessary-copy-initialization] - Use const T& instead of const T[readability-static-definition] - Consider making static definitions inlineUsing "(fix available)" in editors:
| Editor | Command |
|---|---|
| Visual Studio Code | Click 💡 or Ctrl+. |
| JetBrains | Alt+Enter |
| Neovim | :lua vim.lsp.buf.code_action() |
# Format markdown, YAML, JSON, etc.
npx prettier --write README.md
npx prettier --write .github/workflows/*.yml
npx prettier --write FAQ.md
npx prettier --write ".opencode/skills/*/SKILL.md"
Super-linter's NATURAL_LANGUAGE check runs textlint with textlint-rule-terminology
(canonical capitalisation: Git, Ubuntu, SFTP, NixOS, Bash, …). The
repository has no textlint config, so plain npx textlint errors with "No
rules found" — load the rule explicitly via -p:
# Lint a specific file
npx -p textlint -p textlint-rule-terminology textlint --rule terminology AGENTS.md
# Lint every Markdown file in the repo (catches latent errors super-linter misses)
npx -p textlint -p textlint-rule-terminology textlint --rule terminology \
*.md scripts/*.md .github/**/*.md .opencode/skills/*/SKILL.md
# Auto-fix
npx -p textlint -p textlint-rule-terminology textlint --rule terminology --fix \
*.md scripts/*.md .github/**/*.md .opencode/skills/*/SKILL.md
Important: Super-linter only lints the files changed in the PR, so terminology errors in untouched Markdown files sit latent and only blow up when someone next edits that file. When fixing one terminology error, sweep the whole tree with the second command above and clean up any other hits in the same PR.
Prettier auto-fixes many linting issues. Run before act:
# Format all common file types
npx prettier --write "**/*.md" "**/*.yml" "**/*.json" "**/*.html" "**/*.css"
If NATURAL_LANGUAGE fails:
# Run prettier first
npx prettier --write README.md
# Then check again
act push -W .github/workflows/linter.yml -j build
The install-qt-action may fail in local act due to missing downloads. This is expected - real CI works fine.
Some checks need files generated during CI. Run full build first:
qmake6 -r CONFIG+=coverage
make -j4
If gitleaks flags test data:
.gitleaksignore if truly non-sensitiveMake sure act is installed and up to date:
# Check version
act --version
# Update if needed
brew upgrade act # or your package manager
Some linters need secrets or tokens. In local act, these may not be available:
# Pass fake token for codecov
act push -W .github/workflows/ccpp.yml --secret-map "CODECOV_TOKEN=fake"
| File | Purpose |
|---|---|
.github/workflows/linter.yml | Super-linter (many checks) |
.github/workflows/ccpp.yml | Build & test with Qt |
.github/workflows/docs.yml | Doxygen docs generation |
.github/workflows/reuse.yml | REUSE compliance |
.github/super-linter.env | Linter configuration |
THIS IS THE PATTERN - always run before pushing:
# 1. Format files with prettier (always do this)
npx prettier --write "**/*.md" "**/*.yml"
# 2. Verify formatting passes (REQUIRED - catches linting issues)
npx prettier --check "**/*.md"
# 3. Run act linter (recommended before opening PR)
act push -W .github/workflows/linter.yml -j build
# 4. Update with latest main (if branch is behind)
git fetch upstream
git pull upstream main --rebase
# 5. Then push
git push
Note: Prettier catches most issues. act is recommended but may fail on new branches (see below).
act may fail on new branches with error: fatal: ambiguous argument 'HEAD~0'
This is a known issue with the tool, not your code. When this happens:
prettier --check step is sufficient for most casesRecommended alternative - use prettier --check directly:
# This catches most linting issues without needing act
npx prettier --check "**/*.md"
npx prettier --check "**/*.yml"
Before merging a PR, always update it with latest main:
git checkout <branch-name>
git pull upstream main --rebase
git push -f
This prevents "branch is out-of-date with base branch" errors when merging.
For proper code completion and analysis in editors like Visual Studio Code with clangd, generate compile_commands.json:
# Generate compile_commands.json using bear
./scripts/generate-compile-commands.sh
This provides Qt include paths so the LSP can resolve types like QString, QProcess, etc.
Note: compile_commands.json is in .gitignore - regenerate after cleaning or re-configuring.
make check