@@ -57,18 +57,26 @@ if: inputs.enable-signing == 'true'
5757
5858# ## GitHub Workflow Commands
5959
60- Use workflow commands for user-visible messages :
60+ Use workflow commands for user-visible messages with **double colon separator** :
6161
62- ` ` ` yaml
63- # ✅ CORRECT - Shows as annotation in GitHub UI
62+ ` ` ` bash
63+ # ✅ CORRECT - Double colon (::) separator after title
6464echo "::notice title=build::Build completed successfully"
6565echo "::warning title=race-condition::Merge already in progress"
6666echo "::error title=deployment::Failed to deploy"
6767
68- # ❌ WRONG - Just logs to console
68+ # ❌ WRONG - Single colon separator
69+ echo "::notice title=build:Build completed" # Missing second ':'
70+ echo "::warning title=x:message" # Won't display correctly
71+
72+ # ❌ WRONG - Just logs to console (no annotation)
6973echo "Build completed"
7074` ` `
7175
76+ **Syntax pattern:** `::LEVEL title=TITLE::MESSAGE`
77+ - `LEVEL` : notice, warning, or error
78+ - Double `::` separator is required between title and message
79+
7280# # Security Best Practices
7381
7482# ## The secrets[inputs.name] Vulnerability
@@ -427,7 +435,22 @@ Brief description of what the action does.
427435
428436# # Common Gotchas
429437
430- 1. **Boolean input comparisons** : GitHub Actions inputs are strongly typed, with no "JS-like" truthy logic
438+ 1. **Workflow command syntax** : GitHub Actions workflow commands require **double colon separator**
439+ ` ` ` bash
440+ # ✅ CORRECT - Double :: separator
441+ echo "::notice title=success::All tests passed"
442+ echo "::warning title=deprecated::This feature is deprecated"
443+ echo "::error title=failed::Build failed"
444+
445+ # ❌ WRONG - Single : separator (won't display correctly)
446+ echo "::notice title=success:All tests passed"
447+ echo "::warning title=x:message"
448+
449+ # Pattern: ::LEVEL title=TITLE::MESSAGE
450+ # The double :: between title and message is mandatory
451+ ` ` `
452+
453+ 2. **Boolean input comparisons** : GitHub Actions inputs are strongly typed, with no "JS-like" truthy logic
431454 ` ` ` yaml
432455 # ❌ WRONG - Boolean true is NOT equal to string 'true'
433456 on:
@@ -448,12 +471,12 @@ Brief description of what the action does.
448471 if [[ '${{ inputs.enable-feature }}' == 'true' ]]; then # Works in bash
449472 ` ` `
450473
451- 2 . **Expression evaluation in descriptions** : Don't use `${{ }}` in action.yml description fields
452- 3 . **Race conditions** : Always use optimistic execution + error handling, never check-then-act
453- 4 . **Secret exposure** : Never use `secrets[inputs.name]` - always use explicit secret parameters
454- 5 . **Branch deletion** : Use `wait-pending-jobs` before merging to prevent failures in non-required jobs
455- 6 . **Idempotency** : ` gh pr merge --auto` is NOT idempotent - handle "Merge already in progress" error
456- 7 . **TOCTOU vulnerabilities** : State can change between check and action - handle at runtime
474+ 3 . **Expression evaluation in descriptions** : Don't use `${{ }}` in action.yml description fields
475+ 4 . **Race conditions** : Always use optimistic execution + error handling, never check-then-act
476+ 5 . **Secret exposure** : Never use `secrets[inputs.name]` - always use explicit secret parameters
477+ 6 . **Branch deletion** : Use `wait-pending-jobs` before merging to prevent failures in non-required jobs
478+ 7 . **Idempotency** : ` gh pr merge --auto` is NOT idempotent - handle "Merge already in progress" error
479+ 8 . **TOCTOU vulnerabilities** : State can change between check and action - handle at runtime
457480
458481# # Testing Workflows
459482
0 commit comments