Files
actions/.serena/memories/development_standards.md
Ismo Vuorinen 6ebc5a21d5 fix: local references, release workflow (#301)
* fix: local references, release workflow

* chore: apply cr comments
2025-10-23 23:24:20 +03:00

5.7 KiB

Development Standards & Workflows

Quality Standards (ZERO TOLERANCE)

Production Ready Criteria

  • ALL tests pass (100% success rate)
  • ALL linting passes (zero issues)
  • ALL validation checks pass
  • NO warnings or errors

Communication

  • Direct, factual only
  • Never claim "production ready" until literally everything passes
  • No hype, buzzwords, or excessive enthusiasm

Required Commands

Development Cycle

make all        # Complete: docs, format, lint, test
make dev        # Format + lint (development)
make lint       # All linters (MUST pass 100%)
make test       # All tests (MUST pass 100%)
make format     # Auto-fix formatting

Task Completion Checklist

After ANY coding task:

  • make lint - Fix all issues (blocking)
  • make test - Ensure 100% pass
  • EditorConfig compliance verified

Validation System

make update-validators      # Generate validation rules
make update-validators-dry  # Preview changes
make generate-tests         # Create missing tests
make generate-tests-dry     # Preview test generation

Version Management

make release [VERSION=vYYYY.MM.DD]  # Create new release (auto-generates version from date if omitted)
make update-version-refs MAJOR=vYYYY # Update refs to version
make bump-major-version OLD=vYYYY NEW=vYYYY  # Annual bump
make check-version-refs              # Verify current refs

See versioning_system memory for complete details.

Code Style

EditorConfig (BLOCKING ERRORS)

  • Indent: 2 spaces (4 for Python, tabs for Makefile)
  • Charset: UTF-8
  • Line Endings: LF
  • Max Line: 200 chars (120 for Markdown)
  • Final Newline: Required
  • Trailing Whitespace: Trimmed

Shell Scripts (POSIX REQUIRED)

ALL scripts use POSIX shell (#!/bin/sh) for maximum portability:

#!/bin/sh
set -eu                    # MANDATORY (no pipefail - not POSIX)
# Quote everything: "$variable", basename -- "$path"
# Check tools: command -v jq >/dev/null 2>&1
# Use printf instead of echo -e for portability

Why POSIX:

  • Works on Alpine Linux, busybox, minimal containers
  • Faster than bash
  • Maximum compatibility (sh, dash, ash, bash, zsh)
  • CI-friendly, minimal dependencies

Key Differences from Bash:

  • Use #!/bin/sh not #!/usr/bin/env bash
  • Use set -eu not set -euo pipefail (pipefail not POSIX)
  • Use [ ] not [[ ]]
  • Use printf not echo -e
  • Use . file not source file
  • Use cut/grep for parsing, not here-strings <<<
  • Use temp files instead of associative arrays
  • Use $0 not $BASH_SOURCE

Python (Ruff)

  • Line Length: 100 chars
  • Indent: 4 spaces
  • Quotes: Double
  • Docstrings: Google style
  • Type Hints: Required

YAML/Actions

  • Indent: 2 spaces
  • Internal Actions (action.yml): ivuorinen/actions/action-name@<SHA> (SHA-pinned, security)
  • Test Workflows: ./action-name (local reference, runs within repo)
  • Internal Workflows: ./action-name (local reference for sync-labels.yml etc)
  • External Actions: SHA-pinned (not @main/@v1)
  • Step IDs: Required when outputs referenced
  • Permissions: Minimal scope (contents: read default)
  • Output Sanitization: Use printf, never echo for $GITHUB_OUTPUT

Versioning System

Internal References (SHA-Pinned)

All */action.yml files use SHA-pinned references for security and reproducibility:

uses: ivuorinen/actions/validate-inputs@7061aafd35a2f21b57653e34f2b634b2a19334a9

Why SHA-pinned internally:

  • Security: immutable, auditable references
  • Reproducibility: exact version control
  • Portability: works when actions used externally
  • Prevention: no accidental version drift

Test Workflows (Local References)

Test workflows in _tests/ use local references:

uses: ./validate-inputs

Why local in tests: Tests run within the repo, faster, simpler

External User References

Users reference with version tags:

uses: ivuorinen/actions/validate-inputs@v2025

Version Format (CalVer)

  • Major: v2025 (year)
  • Minor: v2025.10 (year.month)
  • Patch: v2025.10.18 (year.month.day)

All three tags point to the same commit SHA.

Creating Releases

make release                     # Auto-generates vYYYY.MM.DD from today's date
make release VERSION=v2025.10.18 # Specific version
git push origin main --tags --force-with-lease

Security Requirements

  1. SHA Pinning: All action references use commit SHAs (not moving tags)
  2. Token Safety: ${{ github.token }}, never hardcoded
  3. Input Validation: All inputs validated via centralized system
  4. Output Sanitization: printf '%s\n' "$value" >> $GITHUB_OUTPUT
  5. Injection Prevention: Validate for ;, &&, |, backticks
  6. Tool Availability: command -v tool checks before use
  7. Variable Quoting: Always "$var" in shell
  8. No Secrets: Never commit credentials/keys

Never Do

  • Never git commit (manual commits not allowed)
  • Never use --no-verify flags
  • Never modify linting config to make tests pass
  • Never assume linting issues are acceptable
  • Never skip testing after changes
  • Never create files unless absolutely necessary
  • Never nest ${{ }} in quoted YAML strings (breaks hashFiles)
  • Never use @main for internal action references (use SHA-pinned)
  • Never use bash-specific features (scripts must be POSIX sh)

Preferred Patterns

  • POSIX shell for all scripts (not bash)
  • SHA-pinned internal action references (security)
  • Edit existing files over creating new ones
  • Use centralized validation for all input handling
  • Follow existing conventions in codebase
  • Actions use composition, not dependencies
  • Custom validators in action directories
  • Convention-based automatic detection