@hybridlabor-api/aos 4.7.2 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/.agents/agents.md +1 -1
  2. package/.agents/nodes.json +1 -1
  3. package/.agents/vendor-manifest.json +23 -1
  4. package/.claude/agents/godmode-media-eventtech.md +1 -1
  5. package/.claude/hooks/conventional-commits.mjs +125 -0
  6. package/.claude/hooks/env-file-protection.mjs +105 -0
  7. package/.claude/hooks/go-gate.mjs +101 -81
  8. package/.claude/settings.json +13 -0
  9. package/.opencode/agents/godmode-media-eventtech.md +1 -1
  10. package/.opencode/plugins/bdb-aos.js +31 -4
  11. package/README.de.md +1 -1
  12. package/README.md +1 -1
  13. package/README.pt.md +1 -1
  14. package/THIRD_PARTY_NOTICES.md +88 -0
  15. package/docs/skills_table.md +1 -1
  16. package/installer.js +309 -101
  17. package/package.json +6 -2
  18. package/packages/aos-cli/README.md +80 -0
  19. package/packages/aos-cli/bin/aos-cli.mjs +134 -0
  20. package/packages/aos-cli/core-skills.json +12 -0
  21. package/packages/aos-cli/extensions/aos.ts +321 -0
  22. package/packages/aos-cli/package-lock.json +1923 -0
  23. package/packages/aos-cli/package.json +29 -0
  24. package/packages/aos-cli/scripts/check-theme.mjs +63 -0
  25. package/packages/aos-cli/themes/aos.json +97 -0
  26. package/scripts/build-plugin-manifest.mjs +131 -0
  27. package/scripts/validate-skills.mjs +81 -6
  28. package/skills/basic/ao-orchestrator/SKILL.md +116 -0
  29. package/skills/global_config/agenttrail/SKILL.md +6 -1
  30. package/skills/global_config/ask-tim/SKILL.md +4 -4
  31. package/skills/global_config/bash-script-generator/SKILL.md +201 -0
  32. package/skills/global_config/bash-script-generator/assets/templates/standard-template.sh +96 -0
  33. package/skills/global_config/bash-script-generator/docs/bash-scripting-guide.md +729 -0
  34. package/skills/global_config/bash-script-generator/docs/generation-best-practices.md +193 -0
  35. package/skills/global_config/bash-script-generator/docs/script-patterns.md +566 -0
  36. package/skills/global_config/bash-script-generator/docs/text-processing-guide.md +437 -0
  37. package/skills/global_config/bash-script-generator/examples/log-analyzer.sh +92 -0
  38. package/skills/global_config/bash-script-generator/scripts/generate_script_template.sh +123 -0
  39. package/skills/global_config/bash-script-generator/scripts/run_ci_checks.sh +172 -0
  40. package/skills/global_config/bash-script-generator/scripts/test_generator.sh +413 -0
  41. package/skills/global_config/bash-script-validator/SKILL.md +249 -0
  42. package/skills/global_config/bash-script-validator/docs/awk-reference.md +449 -0
  43. package/skills/global_config/bash-script-validator/docs/bash-reference.md +468 -0
  44. package/skills/global_config/bash-script-validator/docs/common-mistakes.md +623 -0
  45. package/skills/global_config/bash-script-validator/docs/grep-reference.md +395 -0
  46. package/skills/global_config/bash-script-validator/docs/regex-reference.md +391 -0
  47. package/skills/global_config/bash-script-validator/docs/sed-reference.md +454 -0
  48. package/skills/global_config/bash-script-validator/docs/shell-reference.md +463 -0
  49. package/skills/global_config/bash-script-validator/docs/shellcheck-reference.md +399 -0
  50. package/skills/global_config/bash-script-validator/examples/bad-bash.sh +55 -0
  51. package/skills/global_config/bash-script-validator/examples/bad-shell.sh +54 -0
  52. package/skills/global_config/bash-script-validator/examples/good-bash.sh +71 -0
  53. package/skills/global_config/bash-script-validator/examples/good-shell.sh +69 -0
  54. package/skills/global_config/bash-script-validator/scripts/run_ci_checks.sh +23 -0
  55. package/skills/global_config/bash-script-validator/scripts/shellcheck_wrapper.sh +174 -0
  56. package/skills/global_config/bash-script-validator/scripts/test_validate.sh +446 -0
  57. package/skills/global_config/bash-script-validator/scripts/validate.sh +512 -0
  58. package/skills/global_config/ci-pipeline/SKILL.md +135 -0
  59. package/skills/global_config/dispatching-parallel-agents/SKILL.md +170 -0
  60. package/skills/global_config/dockerfile-generator/SKILL.md +1038 -0
  61. package/skills/global_config/dockerfile-generator/examples/example.dockerignore +95 -0
  62. package/skills/global_config/dockerfile-generator/examples/golang-distroless.Dockerfile +34 -0
  63. package/skills/global_config/dockerfile-generator/examples/java-springboot.Dockerfile +45 -0
  64. package/skills/global_config/dockerfile-generator/examples/nextjs-production.Dockerfile +49 -0
  65. package/skills/global_config/dockerfile-generator/examples/nodejs-multistage.Dockerfile +55 -0
  66. package/skills/global_config/dockerfile-generator/examples/python-fastapi.Dockerfile +48 -0
  67. package/skills/global_config/dockerfile-generator/references/language_specific_guides.md +510 -0
  68. package/skills/global_config/dockerfile-generator/references/multistage_builds.md +570 -0
  69. package/skills/global_config/dockerfile-generator/references/optimization_patterns.md +492 -0
  70. package/skills/global_config/dockerfile-generator/references/security_best_practices.md +375 -0
  71. package/skills/global_config/dockerfile-generator/scripts/generate_dockerignore.sh +199 -0
  72. package/skills/global_config/dockerfile-generator/scripts/generate_golang.sh +172 -0
  73. package/skills/global_config/dockerfile-generator/scripts/generate_java.sh +185 -0
  74. package/skills/global_config/dockerfile-generator/scripts/generate_nodejs.sh +279 -0
  75. package/skills/global_config/dockerfile-generator/scripts/generate_python.sh +218 -0
  76. package/skills/global_config/dockerfile-generator/scripts/test_generator.sh +210 -0
  77. package/skills/global_config/dockerfile-validator/SKILL.md +300 -0
  78. package/skills/global_config/dockerfile-validator/examples/.dockerignore.example +34 -0
  79. package/skills/global_config/dockerfile-validator/examples/bad-example.Dockerfile +37 -0
  80. package/skills/global_config/dockerfile-validator/examples/golang-distroless.Dockerfile +50 -0
  81. package/skills/global_config/dockerfile-validator/examples/good-example.Dockerfile +52 -0
  82. package/skills/global_config/dockerfile-validator/examples/python-optimized.Dockerfile +53 -0
  83. package/skills/global_config/dockerfile-validator/examples/security-issues.Dockerfile +42 -0
  84. package/skills/global_config/dockerfile-validator/references/docker_best_practices.md +348 -0
  85. package/skills/global_config/dockerfile-validator/references/optimization_guide.md +473 -0
  86. package/skills/global_config/dockerfile-validator/references/security_checklist.md +208 -0
  87. package/skills/global_config/dockerfile-validator/scripts/dockerfile-validate.sh +699 -0
  88. package/skills/global_config/dockerfile-validator/scripts/test_validate.sh +35 -0
  89. package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn-lock-read.Dockerfile +6 -0
  90. package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn.Dockerfile +6 -0
  91. package/skills/global_config/dockerfile-validator/tests/fixtures/from-platform-nonroot.Dockerfile +7 -0
  92. package/skills/global_config/dockerfile-validator/tests/test_regression.sh +164 -0
  93. package/skills/global_config/finishing-a-development-branch/SKILL.md +228 -0
  94. package/skills/global_config/github-actions-generator/SKILL.md +353 -0
  95. package/skills/global_config/github-actions-generator/assets/templates/action/composite/action.yml +82 -0
  96. package/skills/global_config/github-actions-generator/assets/templates/action/docker/Dockerfile +25 -0
  97. package/skills/global_config/github-actions-generator/assets/templates/action/docker/action.yml +42 -0
  98. package/skills/global_config/github-actions-generator/assets/templates/action/docker/entrypoint.sh +27 -0
  99. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/action.yml +33 -0
  100. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/index.js +50 -0
  101. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/package.json +27 -0
  102. package/skills/global_config/github-actions-generator/assets/templates/workflow/basic_workflow.yml +242 -0
  103. package/skills/global_config/github-actions-generator/assets/templates/workflow/reusable_workflow.yml +106 -0
  104. package/skills/global_config/github-actions-generator/examples/README.md +147 -0
  105. package/skills/global_config/github-actions-generator/examples/actions/setup-node-cached/action.yml +93 -0
  106. package/skills/global_config/github-actions-generator/examples/caching/docker-buildkit.yml +256 -0
  107. package/skills/global_config/github-actions-generator/examples/security/dependency-review.yml +62 -0
  108. package/skills/global_config/github-actions-generator/examples/security/sbom-attestation.yml +119 -0
  109. package/skills/global_config/github-actions-generator/examples/triggers/chatops-commands.yml +475 -0
  110. package/skills/global_config/github-actions-generator/examples/triggers/repository-dispatch.yml +418 -0
  111. package/skills/global_config/github-actions-generator/examples/triggers/workflow-orchestration.yml +404 -0
  112. package/skills/global_config/github-actions-generator/examples/workflows/docker-build-push.yml +68 -0
  113. package/skills/global_config/github-actions-generator/examples/workflows/go-ci.yml +161 -0
  114. package/skills/global_config/github-actions-generator/examples/workflows/monorepo-ci.yml +340 -0
  115. package/skills/global_config/github-actions-generator/examples/workflows/multi-environment-deploy.yml +406 -0
  116. package/skills/global_config/github-actions-generator/examples/workflows/nodejs-ci.yml +122 -0
  117. package/skills/global_config/github-actions-generator/examples/workflows/python-ci.yml +157 -0
  118. package/skills/global_config/github-actions-generator/examples/workflows/scheduled-tasks.yml +376 -0
  119. package/skills/global_config/github-actions-generator/references/advanced-triggers.md +917 -0
  120. package/skills/global_config/github-actions-generator/references/best-practices.md +755 -0
  121. package/skills/global_config/github-actions-generator/references/common-actions.md +715 -0
  122. package/skills/global_config/github-actions-generator/references/custom-actions.md +320 -0
  123. package/skills/global_config/github-actions-generator/references/expressions-and-contexts.md +688 -0
  124. package/skills/global_config/github-actions-generator/references/modern-features.md +421 -0
  125. package/skills/global_config/github-actions-generator/scripts/test_generator.sh +344 -0
  126. package/skills/global_config/github-actions-templates/SKILL.md +7 -0
  127. package/skills/global_config/github-actions-validator/SKILL.md +576 -0
  128. package/skills/global_config/github-actions-validator/examples/README.md +88 -0
  129. package/skills/global_config/github-actions-validator/examples/outdated-versions.yml +76 -0
  130. package/skills/global_config/github-actions-validator/examples/valid-ci.yml +79 -0
  131. package/skills/global_config/github-actions-validator/examples/with-errors.yml +47 -0
  132. package/skills/global_config/github-actions-validator/references/act_usage.md +233 -0
  133. package/skills/global_config/github-actions-validator/references/action_versions.md +122 -0
  134. package/skills/global_config/github-actions-validator/references/actionlint_usage.md +343 -0
  135. package/skills/global_config/github-actions-validator/references/common_errors.md +512 -0
  136. package/skills/global_config/github-actions-validator/references/modern_features.md +384 -0
  137. package/skills/global_config/github-actions-validator/references/runners.md +317 -0
  138. package/skills/global_config/github-actions-validator/scripts/install_tools.sh +113 -0
  139. package/skills/global_config/github-actions-validator/scripts/validate_workflow.sh +910 -0
  140. package/skills/global_config/github-actions-validator/tests/test_validate_workflow.sh +237 -0
  141. package/skills/global_config/makefile-generator/SKILL.md +614 -0
  142. package/skills/global_config/makefile-generator/assets/templates/.gitkeep +1 -0
  143. package/skills/global_config/makefile-generator/docs/makefile-structure.md +530 -0
  144. package/skills/global_config/makefile-generator/docs/optimization-guide.md +784 -0
  145. package/skills/global_config/makefile-generator/docs/patterns-guide.md +642 -0
  146. package/skills/global_config/makefile-generator/docs/security-guide.md +361 -0
  147. package/skills/global_config/makefile-generator/docs/targets-guide.md +642 -0
  148. package/skills/global_config/makefile-generator/docs/variables-guide.md +596 -0
  149. package/skills/global_config/makefile-generator/scripts/add_standard_targets.sh +539 -0
  150. package/skills/global_config/makefile-generator/scripts/generate_makefile_template.sh +690 -0
  151. package/skills/global_config/makefile-generator/test/test_helper_scripts.sh +190 -0
  152. package/skills/global_config/makefile-validator/SKILL.md +244 -0
  153. package/skills/global_config/makefile-validator/docs/bake-tool.md +1000 -0
  154. package/skills/global_config/makefile-validator/docs/best-practices.md +858 -0
  155. package/skills/global_config/makefile-validator/docs/common-mistakes.md +944 -0
  156. package/skills/global_config/makefile-validator/examples/bad-makefile.mk +77 -0
  157. package/skills/global_config/makefile-validator/examples/good-makefile.mk +103 -0
  158. package/skills/global_config/makefile-validator/scripts/test_validate.sh +382 -0
  159. package/skills/global_config/makefile-validator/scripts/validate_makefile.sh +712 -0
  160. package/skills/global_config/{MCP_Manage → mcp-manage}/SKILL.md +3 -3
  161. package/skills/global_config/requesting-code-review/SKILL.md +98 -0
  162. package/skills/global_config/requesting-code-review/code-reviewer.md +198 -0
  163. package/skills/global_config/using-git-worktrees/SKILL.md +170 -0
  164. package/skills/global_config/verification-before-completion/SKILL.md +123 -0
  165. package/skills/global_config/writing-plans/SKILL.md +126 -46
  166. package/skills/global_config/writing-plans-legacy/SKILL.md +139 -0
@@ -0,0 +1,688 @@
1
+ # GitHub Actions Expressions and Contexts
2
+
3
+ **Last Updated:** November 2025
4
+ **Source:** Official GitHub Actions documentation and Context7 verified examples
5
+
6
+ ## Table of Contents
7
+ 1. [Expression Syntax](#expression-syntax)
8
+ 2. [Contexts](#contexts)
9
+ 3. [Functions](#functions)
10
+ 4. [Operators](#operators)
11
+ 5. [Common Patterns](#common-patterns)
12
+ 6. [Debugging and Troubleshooting](#debugging-and-troubleshooting)
13
+
14
+ ## Expression Syntax
15
+
16
+ GitHub Actions expressions use `${{ }}` syntax to evaluate values dynamically.
17
+
18
+ **Basic Usage:**
19
+ ```yaml
20
+ - name: Print environment
21
+ run: echo "Running on ${{ runner.os }}"
22
+
23
+ - name: Conditional step
24
+ if: ${{ github.ref == 'refs/heads/main' }}
25
+ run: echo "On main branch"
26
+
27
+ # Note: 'if' doesn't require ${{ }}, it's implicit
28
+ - name: Conditional step (preferred)
29
+ if: github.ref == 'refs/heads/main'
30
+ run: echo "On main branch"
31
+ ```
32
+
33
+ **Where Expressions Can Be Used:**
34
+ - `if` conditionals (implicit `${{ }}`, can omit)
35
+ - `env` values (must use `${{ }}`)
36
+ - `with` inputs (must use `${{ }}`)
37
+ - Step `name` values (must use `${{ }}`)
38
+ - Job `outputs` (must use `${{ }}`)
39
+ - `environment.name` (can use expressions for dynamic environments)
40
+
41
+ **Important Notes:**
42
+ - Expressions are interpolated **before** the job is sent to the runner
43
+ - Use environment variables via `env` context for safer variable handling
44
+ - Avoid direct interpolation of untrusted input (use `env` context instead)
45
+
46
+ ## Contexts
47
+
48
+ Contexts are objects containing information about workflow runs, variables, environments, and more.
49
+
50
+ ### github context
51
+
52
+ Contains information about the workflow run and triggering event.
53
+
54
+ **Common Properties:**
55
+ ```yaml
56
+ # Event information
57
+ ${{ github.event_name }} # Event that triggered workflow (push, pull_request, etc.)
58
+ ${{ github.event.action }} # Action that triggered event (opened, synchronize, etc.)
59
+
60
+ # Repository information
61
+ ${{ github.repository }} # owner/repo
62
+ ${{ github.repository_owner }} # Repository owner
63
+ ${{ github.ref }} # Full ref (refs/heads/main, refs/tags/v1.0.0)
64
+ ${{ github.ref_name }} # Short ref (main, v1.0.0)
65
+ ${{ github.sha }} # Commit SHA that triggered workflow
66
+
67
+ # Actor information
68
+ ${{ github.actor }} # Username that triggered workflow
69
+ ${{ github.triggering_actor }} # User that initiated the workflow run
70
+
71
+ # Workflow information
72
+ ${{ github.workflow }} # Workflow name
73
+ ${{ github.run_id }} # Unique workflow run ID
74
+ ${{ github.run_number }} # Workflow run number
75
+ ${{ github.job }} # Current job ID
76
+
77
+ # Pull request information (when event is pull_request)
78
+ ${{ github.event.pull_request.number }}
79
+ ${{ github.event.pull_request.title }}
80
+ ${{ github.event.pull_request.head.ref }} # Source branch
81
+ ${{ github.event.pull_request.base.ref }} # Target branch
82
+ ${{ github.event.pull_request.head.sha }}
83
+
84
+ # Push information (when event is push)
85
+ ${{ github.event.head_commit.message }}
86
+ ${{ github.event.head_commit.author.name }}
87
+ ```
88
+
89
+ **Examples:**
90
+ ```yaml
91
+ # Build image tagged with commit SHA
92
+ - name: Build Docker image
93
+ run: docker build -t myapp:${{ github.sha }} .
94
+
95
+ # Deploy only on main branch
96
+ - name: Deploy
97
+ if: github.ref == 'refs/heads/main'
98
+ run: ./deploy.sh
99
+
100
+ # Different behavior for PR vs push
101
+ - name: Set environment
102
+ run: |
103
+ if [ "${{ github.event_name }}" == "pull_request" ]; then
104
+ echo "ENV=preview" >> $GITHUB_ENV
105
+ else
106
+ echo "ENV=production" >> $GITHUB_ENV
107
+ fi
108
+ ```
109
+
110
+ ### env context
111
+
112
+ Access environment variables defined in workflow, job, or step.
113
+
114
+ ```yaml
115
+ env:
116
+ NODE_VERSION: '20'
117
+ BUILD_TYPE: 'production'
118
+
119
+ jobs:
120
+ build:
121
+ env:
122
+ API_URL: 'https://api.example.com'
123
+ steps:
124
+ - name: Print variables
125
+ run: |
126
+ echo "Node: ${{ env.NODE_VERSION }}"
127
+ echo "API: ${{ env.API_URL }}"
128
+ ```
129
+
130
+ ### runner context
131
+
132
+ Information about the runner executing the job.
133
+
134
+ **Common Properties:**
135
+ ```yaml
136
+ ${{ runner.os }} # OS (Linux, Windows, macOS)
137
+ ${{ runner.arch }} # Architecture (X64, ARM64)
138
+ ${{ runner.name }} # Runner name
139
+ ${{ runner.temp }} # Temp directory path
140
+ ${{ runner.tool_cache }} # Tool cache directory path
141
+ ```
142
+
143
+ **Examples:**
144
+ ```yaml
145
+ # OS-specific commands
146
+ - name: Install dependencies
147
+ run: |
148
+ if [ "${{ runner.os }}" == "Linux" ]; then
149
+ sudo apt-get update
150
+ elif [ "${{ runner.os }}" == "macOS" ]; then
151
+ brew update
152
+ fi
153
+
154
+ # Cache key with OS
155
+ - uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
156
+ with:
157
+ path: ~/.cache
158
+ key: ${{ runner.os }}-cache-${{ hashFiles('**/lock.file') }}
159
+ ```
160
+
161
+ ### secrets context
162
+
163
+ Access encrypted secrets defined in repository or organization settings.
164
+
165
+ ```yaml
166
+ - name: Deploy to production
167
+ env:
168
+ API_KEY: ${{ secrets.API_KEY }}
169
+ DATABASE_URL: ${{ secrets.DATABASE_URL }}
170
+ run: ./deploy.sh
171
+ ```
172
+
173
+ **Security Notes:**
174
+ - Secrets are automatically masked in logs
175
+ - Use `echo "::add-mask::$VALUE"` to mask additional values
176
+ - Pass secrets via environment variables, not command arguments
177
+
178
+ ### matrix context
179
+
180
+ Access matrix configuration values when using matrix strategy.
181
+
182
+ ```yaml
183
+ strategy:
184
+ matrix:
185
+ os: [ubuntu-latest, windows-latest]
186
+ node: [18, 20, 22]
187
+ include:
188
+ - os: ubuntu-latest
189
+ node: 20
190
+ experimental: true
191
+
192
+ steps:
193
+ - name: Setup Node.js ${{ matrix.node }}
194
+ uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
195
+ with:
196
+ node-version: ${{ matrix.node }}
197
+
198
+ - name: Mark experimental
199
+ if: matrix.experimental
200
+ run: echo "Experimental build"
201
+ ```
202
+
203
+ ### steps context
204
+
205
+ Access information about steps that have already run.
206
+
207
+ ```yaml
208
+ steps:
209
+ - name: Run tests
210
+ id: tests
211
+ run: npm test
212
+
213
+ - name: Upload results
214
+ if: steps.tests.outcome == 'success'
215
+ run: ./upload-results.sh
216
+
217
+ - name: Use step output
218
+ run: echo "Test result: ${{ steps.tests.outputs.result }}"
219
+ ```
220
+
221
+ **Step Properties:**
222
+ - `steps.<step_id>.outputs.<output_name>`: Output value
223
+ - `steps.<step_id>.outcome`: Result before `continue-on-error` (`success`, `failure`, `cancelled`, `skipped`)
224
+ - `steps.<step_id>.conclusion`: Final result after `continue-on-error`
225
+
226
+ ### job context
227
+
228
+ Access information about currently running job.
229
+
230
+ ```yaml
231
+ jobs:
232
+ build:
233
+ outputs:
234
+ build-id: ${{ steps.build.outputs.id }}
235
+ steps:
236
+ - name: Build
237
+ id: build
238
+ run: echo "id=build-123" >> $GITHUB_OUTPUT
239
+
240
+ deploy:
241
+ needs: build
242
+ steps:
243
+ - name: Deploy build
244
+ run: ./deploy.sh ${{ needs.build.outputs.build-id }}
245
+ ```
246
+
247
+ ### inputs context
248
+
249
+ Access workflow or reusable workflow inputs.
250
+
251
+ ```yaml
252
+ on:
253
+ workflow_dispatch:
254
+ inputs:
255
+ environment:
256
+ description: 'Environment to deploy'
257
+ required: true
258
+ type: choice
259
+ options: [dev, staging, production]
260
+ debug:
261
+ description: 'Enable debug mode'
262
+ required: false
263
+ type: boolean
264
+ default: false
265
+
266
+ jobs:
267
+ deploy:
268
+ steps:
269
+ - name: Deploy to ${{ inputs.environment }}
270
+ run: ./deploy.sh ${{ inputs.environment }}
271
+
272
+ - name: Enable debug
273
+ if: inputs.debug
274
+ run: echo "Debug mode enabled"
275
+ ```
276
+
277
+ ## Functions
278
+
279
+ ### String Functions
280
+
281
+ **contains()**
282
+ ```yaml
283
+ # Check if string contains substring
284
+ if: contains(github.ref, 'refs/tags/')
285
+ if: contains(github.event.head_commit.message, '[skip ci]')
286
+ if: contains(fromJSON('["main", "develop"]'), github.ref_name)
287
+ ```
288
+
289
+ **startsWith()**
290
+ ```yaml
291
+ # Check if string starts with prefix
292
+ if: startsWith(github.ref, 'refs/tags/v')
293
+ if: startsWith(github.event.pull_request.title, 'feat:')
294
+ ```
295
+
296
+ **endsWith()**
297
+ ```yaml
298
+ # Check if string ends with suffix
299
+ if: endsWith(github.ref, '/main')
300
+ if: endsWith(github.event.pull_request.head.ref, '-hotfix')
301
+ ```
302
+
303
+ **format()**
304
+ ```yaml
305
+ # Format string with placeholders
306
+ - name: Print message
307
+ run: echo "${{ format('Building {0} on {1}', github.ref_name, runner.os) }}"
308
+ ```
309
+
310
+ ### Type Conversion Functions
311
+
312
+ **toJSON()**
313
+ ```yaml
314
+ # Convert object to JSON string
315
+ - name: Print context
316
+ run: echo '${{ toJSON(github) }}'
317
+
318
+ - name: Print matrix
319
+ run: echo '${{ toJSON(matrix) }}'
320
+ ```
321
+
322
+ **fromJSON()**
323
+ ```yaml
324
+ # Parse JSON string to object
325
+ strategy:
326
+ matrix:
327
+ config: ${{ fromJSON('{"versions":[18,20,22]}') }}
328
+
329
+ # Use with dynamic matrix
330
+ jobs:
331
+ setup:
332
+ outputs:
333
+ matrix: ${{ steps.set-matrix.outputs.matrix }}
334
+ steps:
335
+ - id: set-matrix
336
+ run: echo 'matrix={"version":["18","20"]}' >> $GITHUB_OUTPUT
337
+
338
+ build:
339
+ needs: setup
340
+ strategy:
341
+ matrix: ${{ fromJSON(needs.setup.outputs.matrix) }}
342
+ ```
343
+
344
+ ### Hash Functions
345
+
346
+ **hashFiles()**
347
+ ```yaml
348
+ # Generate hash of file contents (for cache keys)
349
+ - uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
350
+ with:
351
+ path: ~/.npm
352
+ key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
353
+
354
+ # Multiple patterns
355
+ key: ${{ hashFiles('**/*.go', '**/go.sum') }}
356
+ ```
357
+
358
+ ### Status Check Functions
359
+
360
+ **success()**
361
+ ```yaml
362
+ # Run only if all previous steps succeeded
363
+ - name: Deploy
364
+ if: success()
365
+ run: ./deploy.sh
366
+ ```
367
+
368
+ **failure()**
369
+ ```yaml
370
+ # Run only if any previous step failed
371
+ - name: Notify on failure
372
+ if: failure()
373
+ run: ./notify-failure.sh
374
+ ```
375
+
376
+ **always()**
377
+ ```yaml
378
+ # Run regardless of previous step status
379
+ - name: Cleanup
380
+ if: always()
381
+ run: ./cleanup.sh
382
+ ```
383
+
384
+ **cancelled()**
385
+ ```yaml
386
+ # Run if workflow was cancelled
387
+ - name: Cleanup on cancel
388
+ if: cancelled()
389
+ run: ./cancel-cleanup.sh
390
+ ```
391
+
392
+ ## Operators
393
+
394
+ ### Comparison Operators
395
+
396
+ ```yaml
397
+ # Equality
398
+ if: github.ref == 'refs/heads/main'
399
+ if: runner.os != 'Windows'
400
+
401
+ # Logical
402
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
403
+ if: github.event_name == 'pull_request' || github.event_name == 'push'
404
+ if: "!(github.event_name == 'pull_request')"
405
+
406
+ # Comparison
407
+ if: github.event.pull_request.changed_files < 10
408
+ if: matrix.node-version >= 20
409
+ ```
410
+
411
+ ### Operator Precedence
412
+
413
+ 1. `()`
414
+ 2. `!`
415
+ 3. `<`, `<=`, `>`, `>=`
416
+ 4. `==`, `!=`
417
+ 5. `&&`
418
+ 6. `||`
419
+
420
+ ## Common Patterns
421
+
422
+ ### Branch-Based Conditions
423
+
424
+ ```yaml
425
+ # Main branch only
426
+ if: github.ref == 'refs/heads/main'
427
+
428
+ # Any branch except main
429
+ if: github.ref != 'refs/heads/main'
430
+
431
+ # Specific branches
432
+ if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'
433
+
434
+ # Tag pushes only
435
+ if: startsWith(github.ref, 'refs/tags/')
436
+
437
+ # Version tags only (v1.0.0 format)
438
+ if: startsWith(github.ref, 'refs/tags/v')
439
+ ```
440
+
441
+ ### Event-Based Conditions
442
+
443
+ ```yaml
444
+ # Push event only
445
+ if: github.event_name == 'push'
446
+
447
+ # PR opened or synchronized
448
+ if: |
449
+ github.event_name == 'pull_request' &&
450
+ (github.event.action == 'opened' || github.event.action == 'synchronize')
451
+
452
+ # Manual dispatch only
453
+ if: github.event_name == 'workflow_dispatch'
454
+
455
+ # Scheduled run only
456
+ if: github.event_name == 'schedule'
457
+ ```
458
+
459
+ ### Step Status Patterns
460
+
461
+ ```yaml
462
+ # Run if specific step succeeded
463
+ if: steps.tests.outcome == 'success'
464
+
465
+ # Run if step failed but continue
466
+ if: steps.tests.outcome == 'failure'
467
+
468
+ # Run cleanup always
469
+ if: always()
470
+
471
+ # Run only on failure
472
+ if: failure()
473
+ ```
474
+
475
+ ### Matrix Patterns
476
+
477
+ ```yaml
478
+ # Specific matrix combination
479
+ if: matrix.os == 'ubuntu-latest' && matrix.node == 20
480
+
481
+ # Exclude certain combinations
482
+ strategy:
483
+ matrix:
484
+ os: [ubuntu, windows, macos]
485
+ node: [18, 20, 22]
486
+ exclude:
487
+ - os: windows
488
+ node: 18
489
+ ```
490
+
491
+ ### Dynamic Values
492
+
493
+ ```yaml
494
+ # Build tags with multiple values
495
+ tags: |
496
+ myapp:latest
497
+ myapp:${{ github.sha }}
498
+ myapp:${{ github.ref_name }}
499
+
500
+ # Conditional environment
501
+ environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
502
+
503
+ # Dynamic timeout
504
+ timeout-minutes: ${{ github.event_name == 'schedule' && 120 || 30 }}
505
+ ```
506
+
507
+ ### Combining Contexts
508
+
509
+ ```yaml
510
+ # Artifact name with context values
511
+ - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
512
+ with:
513
+ name: build-${{ runner.os }}-${{ github.sha }}
514
+ path: dist/
515
+
516
+ # Cache key with multiple factors
517
+ - uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
518
+ with:
519
+ path: ~/.cache
520
+ key: ${{ runner.os }}-${{ hashFiles('**/*.lock') }}-${{ github.ref_name }}
521
+ ```
522
+
523
+ ### Safe String Interpolation
524
+
525
+ ```yaml
526
+ # ❌ UNSAFE: Direct interpolation of user input
527
+ - run: echo "Title: ${{ github.event.pull_request.title }}"
528
+
529
+ # ✅ SAFE: Use environment variables
530
+ - name: Print PR title
531
+ env:
532
+ PR_TITLE: ${{ github.event.pull_request.title }}
533
+ run: echo "Title: $PR_TITLE"
534
+ ```
535
+
536
+ ### JSON Manipulation
537
+
538
+ ```yaml
539
+ # Create dynamic matrix
540
+ - id: set-matrix
541
+ run: |
542
+ if [ "${{ github.event_name }}" == "push" ]; then
543
+ echo 'matrix={"os":["ubuntu","windows","macos"]}' >> $GITHUB_OUTPUT
544
+ else
545
+ echo 'matrix={"os":["ubuntu"]}' >> $GITHUB_OUTPUT
546
+ fi
547
+
548
+ # Use matrix
549
+ strategy:
550
+ matrix: ${{ fromJSON(steps.set-matrix.outputs.matrix) }}
551
+ ```
552
+
553
+ ## Debugging and Troubleshooting
554
+
555
+ ### Dumping Contexts to Logs
556
+
557
+ The most effective way to debug workflow issues is to dump context information to logs:
558
+
559
+ **Dump All Contexts:**
560
+ ```yaml
561
+ name: Context Debugging
562
+ on: push
563
+
564
+ jobs:
565
+ dump_contexts:
566
+ runs-on: ubuntu-latest
567
+ steps:
568
+ - name: Dump GitHub context
569
+ env:
570
+ GITHUB_CONTEXT: ${{ toJson(github) }}
571
+ run: echo "$GITHUB_CONTEXT"
572
+
573
+ - name: Dump job context
574
+ env:
575
+ JOB_CONTEXT: ${{ toJson(job) }}
576
+ run: echo "$JOB_CONTEXT"
577
+
578
+ - name: Dump steps context
579
+ env:
580
+ STEPS_CONTEXT: ${{ toJson(steps) }}
581
+ run: echo "$STEPS_CONTEXT"
582
+
583
+ - name: Dump runner context
584
+ env:
585
+ RUNNER_CONTEXT: ${{ toJson(runner) }}
586
+ run: echo "$RUNNER_CONTEXT"
587
+
588
+ - name: Dump strategy context
589
+ env:
590
+ STRATEGY_CONTEXT: ${{ toJson(strategy) }}
591
+ run: echo "$STRATEGY_CONTEXT"
592
+
593
+ - name: Dump matrix context
594
+ env:
595
+ MATRIX_CONTEXT: ${{ toJson(matrix) }}
596
+ run: echo "$MATRIX_CONTEXT"
597
+ ```
598
+
599
+ **Example Runner Context Output:**
600
+ ```json
601
+ {
602
+ "os": "Linux",
603
+ "arch": "X64",
604
+ "name": "GitHub Actions 2",
605
+ "tool_cache": "/opt/hostedtoolcache",
606
+ "temp": "/home/runner/work/_temp"
607
+ }
608
+ ```
609
+
610
+ ### Safe Variable Interpolation
611
+
612
+ **Best Practice - Use env context:**
613
+ ```yaml
614
+ # ✅ SAFE: Interpolate before runner execution
615
+ - name: Greet user
616
+ env:
617
+ GREETING: ${{ env.Greeting }}
618
+ FIRST_NAME: ${{ env.First_Name }}
619
+ DAY: ${{ env.DAY_OF_WEEK }}
620
+ run: echo "$GREETING $FIRST_NAME. Today is $DAY!"
621
+ ```
622
+
623
+ This approach ensures variables are resolved by GitHub Actions before execution, providing consistent behavior.
624
+
625
+ ## Tips and Best Practices
626
+
627
+ 1. **Implicit vs Explicit `${{ }}`:**
628
+ - `if` conditions don't need `${{ }}` (implicit)
629
+ - Other contexts require explicit `${{ }}`
630
+
631
+ 2. **String Comparisons:**
632
+ - Always use quotes for string literals
633
+ - Case-sensitive by default
634
+
635
+ 3. **Boolean Values:**
636
+ - Use `true` and `false` without quotes
637
+ - Empty strings evaluate to `false`
638
+
639
+ 4. **Default Values:**
640
+ ```yaml
641
+ # Use || for default values
642
+ environment: ${{ inputs.environment || 'dev' }}
643
+ ```
644
+
645
+ 5. **Multi-line Expressions:**
646
+ ```yaml
647
+ if: |
648
+ github.event_name == 'push' &&
649
+ github.ref == 'refs/heads/main' &&
650
+ !contains(github.event.head_commit.message, '[skip ci]')
651
+ ```
652
+
653
+ 6. **Security Best Practices:**
654
+ - Always use `env` context for untrusted input
655
+ - Never directly interpolate user-controlled values
656
+ - Use `::add-mask::` for sensitive values
657
+
658
+ 7. **Dynamic Environment Names:**
659
+ ```yaml
660
+ environment:
661
+ name: ${{ github.ref_name }} # Dynamic based on branch
662
+ ```
663
+
664
+ 8. **Debugging Expressions:**
665
+ ```yaml
666
+ # Print entire context with pretty formatting
667
+ - run: echo '${{ toJson(github) }}'
668
+
669
+ # Print specific values
670
+ - run: |
671
+ echo "Event: ${{ github.event_name }}"
672
+ echo "Ref: ${{ github.ref }}"
673
+ echo "SHA: ${{ github.sha }}"
674
+ echo "Actor: ${{ github.actor }}"
675
+ ```
676
+
677
+ ## Summary
678
+
679
+ - Use `${{ }}` for dynamic values
680
+ - Access contexts like `github`, `env`, `secrets`, `matrix`, `runner`, etc.
681
+ - Use functions for string manipulation, hashing, and type conversion (`toJSON`, `hashFiles`, `contains`, etc.)
682
+ - Combine operators for complex conditions
683
+ - **Always validate and sanitize user inputs for security**
684
+ - Use `env` context for untrusted input instead of direct interpolation
685
+ - Debug with `toJSON()` to dump context information
686
+ - Expressions are evaluated before job execution on the runner
687
+
688
+ **Security Warning:** Never directly interpolate untrusted input (PR titles, issue bodies, user input) in `run` commands. Always use environment variables via the `env` context.