opencode-skills-collection 4.0.54 → 4.0.55
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.
- package/bundled-skills/.antigravity-install-manifest.json +1 -1
- package/bundled-skills/antigravity-maintainer-batch-release/SKILL.md +10 -1
- package/bundled-skills/backend-security-coder/resources/implementation-playbook.md +23 -0
- package/bundled-skills/business-analyst/resources/implementation-playbook.md +23 -0
- package/bundled-skills/devops-troubleshooter/resources/implementation-playbook.md +23 -0
- package/bundled-skills/distributed-tracing/SKILL.md +22 -435
- package/bundled-skills/distributed-tracing/references/instrumentation.md +13 -0
- package/bundled-skills/distributed-tracing/references/jaeger-setup.md +13 -0
- package/bundled-skills/distributed-tracing/resources/implementation-playbook.md +23 -0
- package/bundled-skills/django-pro/resources/implementation-playbook.md +23 -0
- package/bundled-skills/embedding-strategies/SKILL.md +40 -64
- package/bundled-skills/embedding-strategies/resources/implementation-playbook.md +23 -0
- package/bundled-skills/fastapi-pro/resources/implementation-playbook.md +23 -0
- package/bundled-skills/find-complementary-founders/scripts/assess_profile.py +7 -1
- package/bundled-skills/frontend-security-coder/SKILL.md +5 -5
- package/bundled-skills/frontend-security-coder/resources/implementation-playbook.md +23 -0
- package/bundled-skills/github-actions-templates/SKILL.md +34 -314
- package/bundled-skills/github-actions-templates/references/common-workflows.md +13 -0
- package/bundled-skills/github-actions-templates/resources/implementation-playbook.md +23 -0
- package/bundled-skills/google-docs-automation/SKILL.md +19 -69
- package/bundled-skills/google-sheets-automation/SKILL.md +20 -128
- package/bundled-skills/google-slides-automation/SKILL.md +19 -128
- package/bundled-skills/grafana-dashboards/SKILL.md +6 -6
- package/bundled-skills/grafana-dashboards/references/dashboard-design.md +13 -0
- package/bundled-skills/grafana-dashboards/resources/implementation-playbook.md +23 -0
- package/bundled-skills/incident-responder/resources/implementation-playbook.md +23 -0
- package/bundled-skills/instagram/scripts/config.py +33 -8
- package/bundled-skills/ios-developer/resources/implementation-playbook.md +23 -0
- package/bundled-skills/junta-leiloeiros/scripts/.snyk +5 -0
- package/bundled-skills/junta-leiloeiros/scripts/requirements.txt +2 -0
- package/bundled-skills/kpi-dashboard-design/SKILL.md +7 -67
- package/bundled-skills/kpi-dashboard-design/resources/implementation-playbook.md +23 -0
- package/bundled-skills/kpi-dashboard-design/resources/metric-queries.sql +30 -0
- package/bundled-skills/lint-and-validate/SKILL.md +17 -45
- package/bundled-skills/lint-and-validate/scripts/lint_runner.py +17 -8
- package/bundled-skills/lint-and-validate/scripts/type_coverage.py +77 -167
- package/bundled-skills/mobile-developer/resources/implementation-playbook.md +23 -0
- package/bundled-skills/multi-platform-apps-multi-platform/resources/implementation-playbook.md +23 -0
- package/bundled-skills/notebooklm/scripts/config.py +33 -11
- package/bundled-skills/observability-and-instrumentation/SKILL.md +4 -1
- package/bundled-skills/observability-and-instrumentation/references/observability-checklist.md +13 -0
- package/bundled-skills/pci-compliance/SKILL.md +23 -469
- package/bundled-skills/pci-compliance/resources/implementation-playbook.md +23 -0
- package/bundled-skills/postmortem-writing/SKILL.md +1 -1
- package/bundled-skills/postmortem-writing/resources/implementation-playbook.md +23 -0
- package/bundled-skills/pydantic-models-py/SKILL.md +1 -3
- package/bundled-skills/secrets-management/SKILL.md +24 -349
- package/bundled-skills/secrets-management/references/github-secrets.md +13 -0
- package/bundled-skills/secrets-management/references/vault-setup.md +13 -0
- package/bundled-skills/security-and-hardening/SKILL.md +8 -6
- package/bundled-skills/security-and-hardening/references/security-checklist.md +13 -0
- package/bundled-skills/seo-content-planner/resources/implementation-playbook.md +23 -0
- package/bundled-skills/seo-content-writer/SKILL.md +2 -2
- package/bundled-skills/seo-content-writer/resources/implementation-playbook.md +23 -0
- package/bundled-skills/shopify-development/scripts/.snyk +3 -0
- package/bundled-skills/slack-gif-creator/.snyk +5 -0
- package/bundled-skills/slack-gif-creator/requirements.txt +2 -2
- package/bundled-skills/slo-implementation/SKILL.md +24 -9
- package/bundled-skills/slo-implementation/references/error-budget.md +13 -0
- package/bundled-skills/slo-implementation/references/slo-definitions.md +13 -0
- package/bundled-skills/slo-implementation/resources/implementation-playbook.md +23 -0
- package/bundled-skills/sql-optimization-patterns/SKILL.md +10 -6
- package/bundled-skills/sql-optimization-patterns/resources/implementation-playbook.md +52 -56
- package/bundled-skills/telegram/assets/boilerplate/nodejs/package-lock.json +1888 -0
- package/bundled-skills/telegram/assets/boilerplate/nodejs/package.json +3 -0
- package/bundled-skills/vector-database-engineer/resources/implementation-playbook.md +23 -0
- package/bundled-skills/videodb/scripts/ws_listener.py +8 -1
- package/bundled-skills/whatsapp-cloud-api/assets/boilerplate/nodejs/package-lock.json +1881 -0
- package/bundled-skills/whatsapp-cloud-api/assets/boilerplate/nodejs/package.json +3 -0
- package/bundled-skills/whatsapp-cloud-api/assets/boilerplate/python/.snyk +3 -0
- package/package.json +1 -1
|
@@ -115,9 +115,11 @@ class LocalEmbedder:
|
|
|
115
115
|
def __init__(
|
|
116
116
|
self,
|
|
117
117
|
model_name: str = "BAAI/bge-large-en-v1.5",
|
|
118
|
-
device: str = "
|
|
118
|
+
device: str = "cpu",
|
|
119
|
+
query_prefix: str = ""
|
|
119
120
|
):
|
|
120
121
|
self.model = SentenceTransformer(model_name, device=device)
|
|
122
|
+
self.query_prefix = query_prefix # Choose from the selected model card.
|
|
121
123
|
|
|
122
124
|
def embed(
|
|
123
125
|
self,
|
|
@@ -135,11 +137,8 @@ class LocalEmbedder:
|
|
|
135
137
|
return embeddings
|
|
136
138
|
|
|
137
139
|
def embed_query(self, query: str) -> np.ndarray:
|
|
138
|
-
"""Embed a query with
|
|
139
|
-
|
|
140
|
-
if "bge" in self.model.get_sentence_embedding_dimension():
|
|
141
|
-
query = f"Represent this sentence for searching relevant passages: {query}"
|
|
142
|
-
return self.embed([query])[0]
|
|
140
|
+
"""Embed a query with the explicitly configured model prefix."""
|
|
141
|
+
return self.embed([self.query_prefix + query])[0]
|
|
143
142
|
|
|
144
143
|
def embed_documents(self, documents: List[str]) -> np.ndarray:
|
|
145
144
|
"""Embed documents for indexing."""
|
|
@@ -171,8 +170,13 @@ def chunk_by_tokens(
|
|
|
171
170
|
tokenizer=None
|
|
172
171
|
) -> List[str]:
|
|
173
172
|
"""Chunk text by token count."""
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
if not isinstance(chunk_size, int) or not isinstance(chunk_overlap, int):
|
|
174
|
+
raise ValueError("chunk size and overlap must be integers")
|
|
175
|
+
if chunk_size <= 0 or not 0 <= chunk_overlap < chunk_size:
|
|
176
|
+
raise ValueError("require chunk_size > 0 and 0 <= overlap < chunk_size")
|
|
177
|
+
if tokenizer is None:
|
|
178
|
+
import tiktoken
|
|
179
|
+
tokenizer = tiktoken.get_encoding("cl100k_base")
|
|
176
180
|
|
|
177
181
|
tokens = tokenizer.encode(text)
|
|
178
182
|
chunks = []
|
|
@@ -183,6 +187,8 @@ def chunk_by_tokens(
|
|
|
183
187
|
chunk_tokens = tokens[start:end]
|
|
184
188
|
chunk_text = tokenizer.decode(chunk_tokens)
|
|
185
189
|
chunks.append(chunk_text)
|
|
190
|
+
if end >= len(tokens):
|
|
191
|
+
break
|
|
186
192
|
start = end - chunk_overlap
|
|
187
193
|
|
|
188
194
|
return chunks
|
|
@@ -249,58 +255,28 @@ def recursive_character_splitter(
|
|
|
249
255
|
chunk_overlap: int = 200,
|
|
250
256
|
separators: List[str] = None
|
|
251
257
|
) -> List[str]:
|
|
252
|
-
"""
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if current_length + split_length > chunk_size and current_chunk:
|
|
275
|
-
chunk_text = separator.join(current_chunk)
|
|
276
|
-
|
|
277
|
-
# Recursively split if still too large
|
|
278
|
-
if len(chunk_text) > chunk_size and remaining_separators:
|
|
279
|
-
chunks.extend(split_text(chunk_text, remaining_separators))
|
|
280
|
-
else:
|
|
281
|
-
chunks.append(chunk_text)
|
|
282
|
-
|
|
283
|
-
# Start new chunk with overlap
|
|
284
|
-
overlap_splits = []
|
|
285
|
-
overlap_length = 0
|
|
286
|
-
for s in reversed(current_chunk):
|
|
287
|
-
if overlap_length + len(s) <= chunk_overlap:
|
|
288
|
-
overlap_splits.insert(0, s)
|
|
289
|
-
overlap_length += len(s)
|
|
290
|
-
else:
|
|
291
|
-
break
|
|
292
|
-
current_chunk = overlap_splits
|
|
293
|
-
current_length = overlap_length
|
|
294
|
-
|
|
295
|
-
current_chunk.append(split)
|
|
296
|
-
current_length += split_length
|
|
297
|
-
|
|
298
|
-
if current_chunk:
|
|
299
|
-
chunks.append(separator.join(current_chunk))
|
|
300
|
-
|
|
301
|
-
return chunks
|
|
302
|
-
|
|
303
|
-
return split_text(text, separators)
|
|
258
|
+
"""Bounded character chunks, preferring a separator inside each window."""
|
|
259
|
+
if chunk_size <= 0 or not 0 <= chunk_overlap < chunk_size:
|
|
260
|
+
raise ValueError("require chunk_size > 0 and 0 <= overlap < chunk_size")
|
|
261
|
+
separators = separators or ["\n\n", "\n", ". ", " "]
|
|
262
|
+
chunks = []
|
|
263
|
+
start = 0
|
|
264
|
+
while start < len(text):
|
|
265
|
+
end = min(start + chunk_size, len(text))
|
|
266
|
+
if end < len(text):
|
|
267
|
+
for separator in separators:
|
|
268
|
+
if not separator:
|
|
269
|
+
continue
|
|
270
|
+
boundary = text.rfind(separator, start + chunk_overlap + 1, end)
|
|
271
|
+
if boundary >= 0:
|
|
272
|
+
end = boundary + len(separator)
|
|
273
|
+
break
|
|
274
|
+
chunks.append(text[start:end])
|
|
275
|
+
if end == len(text):
|
|
276
|
+
break
|
|
277
|
+
start = end - chunk_overlap
|
|
278
|
+
return chunks
|
|
279
|
+
|
|
304
280
|
```
|
|
305
281
|
|
|
306
282
|
### Template 4: Domain-Specific Embedding Pipeline
|
|
@@ -381,8 +357,8 @@ class DomainEmbeddingPipeline:
|
|
|
381
357
|
class CodeEmbeddingPipeline:
|
|
382
358
|
"""Specialized pipeline for code embeddings."""
|
|
383
359
|
|
|
384
|
-
def __init__(self,
|
|
385
|
-
self.
|
|
360
|
+
def __init__(self, embed_fn):
|
|
361
|
+
self.embed_fn = embed_fn # Supply a reviewed provider-specific embedding adapter.
|
|
386
362
|
|
|
387
363
|
def chunk_code(self, code: str, language: str) -> List[dict]:
|
|
388
364
|
"""Chunk code by functions/classes."""
|
|
@@ -391,12 +367,12 @@ class CodeEmbeddingPipeline:
|
|
|
391
367
|
# Parse with tree-sitter
|
|
392
368
|
# Extract functions, classes, methods
|
|
393
369
|
# Return chunks with context
|
|
394
|
-
|
|
370
|
+
raise NotImplementedError("Supply the installed parser and language grammar")
|
|
395
371
|
|
|
396
372
|
def embed_with_context(self, chunk: str, context: str) -> List[float]:
|
|
397
373
|
"""Embed code with surrounding context."""
|
|
398
374
|
combined = f"Context: {context}\n\nCode:\n{chunk}"
|
|
399
|
-
return
|
|
375
|
+
return self.embed_fn(combined)
|
|
400
376
|
```
|
|
401
377
|
|
|
402
378
|
### Template 5: Embedding Quality Evaluation
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Embedding selection and migration
|
|
2
|
+
|
|
3
|
+
## Inputs
|
|
4
|
+
|
|
5
|
+
Representative documents, query/relevance pairs, data-sharing permission, installed provider SDK and latency/cost constraints.
|
|
6
|
+
|
|
7
|
+
## Procedure
|
|
8
|
+
|
|
9
|
+
1. Choose candidate models from their actual supported languages, token limits, dimensions and query/document instructions. Record model revision and preprocessing together.
|
|
10
|
+
2. Validate chunk-size and overlap bounds; test empty input and an overlong document. Preserve identifiers and source offsets. Batch only within provider limits and keep original text intact.
|
|
11
|
+
3. Compare retrieval on the same labeled queries, including no-answer and cross-tenant cases. Use a separate index for each model and dimension; verify rollback before switching readers.
|
|
12
|
+
|
|
13
|
+
## Worked example
|
|
14
|
+
|
|
15
|
+
Evaluate two models against twenty labeled support queries. Report recall at a fixed k, latency and failures; do not describe this small sample as general superiority.
|
|
16
|
+
|
|
17
|
+
## Verification and handoff
|
|
18
|
+
|
|
19
|
+
Report the actual files or configuration changed, checks performed, observed results and any untested environment. Keep the original inputs and evidence sufficient to reproduce the conclusion.
|
|
20
|
+
|
|
21
|
+
## Limitations
|
|
22
|
+
|
|
23
|
+
Embeddings may expose private source information. Do not send documents to a provider without authorization, or mix vectors from different model revisions.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# FastAPI endpoint implementation
|
|
2
|
+
|
|
3
|
+
## Inputs
|
|
4
|
+
|
|
5
|
+
Installed FastAPI/Pydantic/SQLAlchemy versions, endpoint contract, identity model and test database.
|
|
6
|
+
|
|
7
|
+
## Procedure
|
|
8
|
+
|
|
9
|
+
1. Define request and response schemas from the user journey. Keep ownership and permission decisions server-side and separate from serialization.
|
|
10
|
+
2. Reuse application lifespan and dependency patterns. Bound outbound timeouts; avoid blocking calls in async handlers and avoid sharing mutable database sessions across concurrent tasks.
|
|
11
|
+
3. Test success, invalid input, unauthorized access and persistence failure. Verify response fields, transaction rollback and client-visible errors before updating the API contract.
|
|
12
|
+
|
|
13
|
+
## Worked example
|
|
14
|
+
|
|
15
|
+
Create an invoice endpoint with an idempotency requirement. Repeating the same request must not create a second invoice; a different tenant must not retrieve the first.
|
|
16
|
+
|
|
17
|
+
## Verification and handoff
|
|
18
|
+
|
|
19
|
+
Report the actual files or configuration changed, checks performed, observed results and any untested environment. Keep the original inputs and evidence sufficient to reproduce the conclusion.
|
|
20
|
+
|
|
21
|
+
## Limitations
|
|
22
|
+
|
|
23
|
+
Background work and external effects require their own retry and idempotency design. Schema validation is not authorization.
|
|
@@ -8,6 +8,7 @@ import json
|
|
|
8
8
|
import os
|
|
9
9
|
import re
|
|
10
10
|
import sys
|
|
11
|
+
import stat
|
|
11
12
|
from collections import defaultdict
|
|
12
13
|
from datetime import date, datetime, timezone
|
|
13
14
|
from pathlib import Path
|
|
@@ -395,9 +396,14 @@ def write_json(path: Path, data: dict, *, private: bool) -> None:
|
|
|
395
396
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
396
397
|
if path.is_symlink():
|
|
397
398
|
raise ProfileError(f"Refusing to write through symlink: {path}")
|
|
398
|
-
flags = os.O_WRONLY | os.O_CREAT |
|
|
399
|
+
flags = os.O_WRONLY | os.O_CREAT | getattr(os, "O_NOFOLLOW", 0)
|
|
400
|
+
flags |= getattr(os, "O_NONBLOCK", 0)
|
|
399
401
|
fd = os.open(path, flags, 0o600 if private else 0o644)
|
|
400
402
|
with os.fdopen(fd, "w", encoding="utf-8") as handle:
|
|
403
|
+
file_stat = os.fstat(handle.fileno())
|
|
404
|
+
if not stat.S_ISREG(file_stat.st_mode) or file_stat.st_nlink != 1:
|
|
405
|
+
raise ProfileError(f"Refusing to write non-regular or multiply linked file: {path}")
|
|
406
|
+
os.ftruncate(handle.fileno(), 0)
|
|
401
407
|
os.fchmod(handle.fileno(), 0o600 if private else 0o644)
|
|
402
408
|
json.dump(data, handle, indent=2, ensure_ascii=False, sort_keys=True)
|
|
403
409
|
handle.write("\n")
|
|
@@ -68,13 +68,13 @@ Expert frontend security developer with comprehensive knowledge of client-side s
|
|
|
68
68
|
- **Third-party CSS**: External stylesheet validation, subresource integrity for stylesheets
|
|
69
69
|
|
|
70
70
|
### Clickjacking Protection
|
|
71
|
-
- **Frame detection**:
|
|
71
|
+
- **Frame detection**: Supplementary UI signals only; do not treat viewport observation as a frame authorization boundary
|
|
72
72
|
- **Frame-busting techniques**: JavaScript-based frame busting, top-level navigation protection
|
|
73
73
|
- **X-Frame-Options**: DENY and SAMEORIGIN implementation, frame ancestor control
|
|
74
74
|
- **CSP frame-ancestors**: Content Security Policy frame protection, granular frame source control
|
|
75
75
|
- **SameSite cookie protection**: Cross-frame CSRF protection, cookie isolation techniques
|
|
76
76
|
- **Visual confirmation**: User action confirmation, critical operation verification, overlay detection
|
|
77
|
-
- **Environment-specific deployment**:
|
|
77
|
+
- **Environment-specific deployment**: Define an explicit allowed embedding policy per environment; do not disable protection as a convenience
|
|
78
78
|
|
|
79
79
|
### Secure Redirects and Navigation
|
|
80
80
|
- **Redirect validation**: URL allowlist validation, internal redirect verification, domain allowlist enforcement
|
|
@@ -117,7 +117,7 @@ Expert frontend security developer with comprehensive knowledge of client-side s
|
|
|
117
117
|
|
|
118
118
|
### Mobile and Responsive Security
|
|
119
119
|
- **Touch interaction security**: Gesture validation, touch event security, haptic feedback
|
|
120
|
-
- **Viewport security**: Secure viewport configuration, zoom
|
|
120
|
+
- **Viewport security**: Secure viewport configuration, preserve user zoom and accessible scaling
|
|
121
121
|
- **Device API security**: Geolocation privacy, camera/microphone permissions, sensor data protection
|
|
122
122
|
- **App-like behavior**: PWA security, full-screen mode security, navigation gesture handling
|
|
123
123
|
- **Cross-platform compatibility**: Platform-specific security considerations, feature detection security
|
|
@@ -127,7 +127,7 @@ Expert frontend security developer with comprehensive knowledge of client-side s
|
|
|
127
127
|
- Implements comprehensive input validation with allowlist approaches
|
|
128
128
|
- Uses Content Security Policy headers to prevent script injection
|
|
129
129
|
- Validates all user-supplied URLs before navigation or redirects
|
|
130
|
-
-
|
|
130
|
+
- Uses server-delivered frame-ancestors policy; frame detection is only supplementary
|
|
131
131
|
- Sanitizes all dynamic content with established libraries like DOMPurify
|
|
132
132
|
- Implements secure authentication token storage and management
|
|
133
133
|
- Uses modern browser security features and APIs
|
|
@@ -151,7 +151,7 @@ Expert frontend security developer with comprehensive knowledge of client-side s
|
|
|
151
151
|
2. **Implement secure DOM manipulation** using textContent and secure APIs
|
|
152
152
|
3. **Configure Content Security Policy** with appropriate directives and violation reporting
|
|
153
153
|
4. **Validate all user inputs** with allowlist-based validation and sanitization
|
|
154
|
-
5. **Implement clickjacking protection** with frame
|
|
154
|
+
5. **Implement clickjacking protection** with server-delivered frame-ancestors policy and authorized embedding tests
|
|
155
155
|
6. **Secure navigation and redirects** with URL validation and allowlist enforcement
|
|
156
156
|
7. **Apply browser security features** including SRI, Trusted Types, and security headers
|
|
157
157
|
8. **Handle authentication securely** with proper token storage and session management
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Frontend security implementation
|
|
2
|
+
|
|
3
|
+
## Inputs
|
|
4
|
+
|
|
5
|
+
The component, rendering framework, trusted content policy, session design and browser test route.
|
|
6
|
+
|
|
7
|
+
## Procedure
|
|
8
|
+
|
|
9
|
+
1. Identify untrusted text, HTML, URLs and cross-window messages. Prefer text rendering; use an established sanitizer only where authored HTML is required.
|
|
10
|
+
2. Enforce URL schemes and destination rules. Validate message origin and source. Coordinate server headers and authorization; client validation is only usability feedback.
|
|
11
|
+
3. Test an inert markup payload as text, disallowed URL schemes and messages from another origin. Inspect rendered DOM, network effects and console. Preserve zoom and keyboard access.
|
|
12
|
+
|
|
13
|
+
## Worked example
|
|
14
|
+
|
|
15
|
+
A profile biography contains markup. Render it as text unless rich text is explicitly required; verify no extra element or request appears and legitimate text remains readable.
|
|
16
|
+
|
|
17
|
+
## Verification and handoff
|
|
18
|
+
|
|
19
|
+
Report the actual files or configuration changed, checks performed, observed results and any untested environment. Keep the original inputs and evidence sufficient to reproduce the conclusion.
|
|
20
|
+
|
|
21
|
+
## Limitations
|
|
22
|
+
|
|
23
|
+
Frame detection and frame-busting scripts do not replace frame-ancestors response policy. Browser storage is not a safe place for server secrets.
|
|
@@ -6,348 +6,68 @@ source: community
|
|
|
6
6
|
date_added: "2026-02-27"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
# GitHub Actions
|
|
9
|
+
# GitHub Actions Workflow Patterns
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## When to Use
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Implement testing, matrix builds, artifact preparation or an explicitly authorized deployment workflow for an existing repository.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
- You need a different domain or tool outside this scope
|
|
15
|
+
## Inputs
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
Inspect the repository's actual scripts, lockfile, supported runtimes, required check names and release policy. Read `resources/implementation-playbook.md` and `references/common-workflows.md` before choosing job boundaries.
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
- Apply relevant best practices and validate outcomes.
|
|
22
|
-
- Provide actionable steps and verification.
|
|
23
|
-
- If detailed examples are required, open `resources/implementation-playbook.md`.
|
|
19
|
+
## Test Workflow
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Create efficient, secure GitHub Actions workflows for continuous integration and deployment across various tech stacks.
|
|
28
|
-
|
|
29
|
-
## Use this skill when
|
|
30
|
-
|
|
31
|
-
- Automate testing and deployment
|
|
32
|
-
- Build Docker images and push to registries
|
|
33
|
-
- Deploy to Kubernetes clusters
|
|
34
|
-
- Run security scans
|
|
35
|
-
- Implement matrix builds for multiple environments
|
|
36
|
-
|
|
37
|
-
## Common Workflow Patterns
|
|
38
|
-
|
|
39
|
-
### Pattern 1: Test Workflow
|
|
21
|
+
This Node example assumes the target repository declares `npm test` and supports Node 22. Adapt the runtime and command to the actual project. The pinned action revisions are explicit review inputs; verify them before adopting or updating the template.
|
|
40
22
|
|
|
41
23
|
```yaml
|
|
42
24
|
name: Test
|
|
43
|
-
|
|
44
25
|
on:
|
|
45
|
-
push:
|
|
46
|
-
branches: [ main, develop ]
|
|
47
26
|
pull_request:
|
|
48
|
-
branches: [ main ]
|
|
49
|
-
|
|
50
|
-
jobs:
|
|
51
|
-
test:
|
|
52
|
-
runs-on: ubuntu-latest
|
|
53
|
-
|
|
54
|
-
strategy:
|
|
55
|
-
matrix:
|
|
56
|
-
node-version: [18.x, 20.x]
|
|
57
|
-
|
|
58
|
-
steps:
|
|
59
|
-
- uses: actions/checkout@v4
|
|
60
|
-
|
|
61
|
-
- name: Use Node.js ${{ matrix.node-version }}
|
|
62
|
-
uses: actions/setup-node@v4
|
|
63
|
-
with:
|
|
64
|
-
node-version: ${{ matrix.node-version }}
|
|
65
|
-
cache: 'npm'
|
|
66
|
-
|
|
67
|
-
- name: Install dependencies
|
|
68
|
-
run: npm ci
|
|
69
|
-
|
|
70
|
-
- name: Run linter
|
|
71
|
-
run: npm run lint
|
|
72
|
-
|
|
73
|
-
- name: Run tests
|
|
74
|
-
run: npm test
|
|
75
|
-
|
|
76
|
-
- name: Upload coverage
|
|
77
|
-
uses: codecov/codecov-action@v3
|
|
78
|
-
with:
|
|
79
|
-
files: ./coverage/lcov.info
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
**Reference:** See `assets/test-workflow.yml`
|
|
83
|
-
|
|
84
|
-
### Pattern 2: Build and Push Docker Image
|
|
85
|
-
|
|
86
|
-
```yaml
|
|
87
|
-
name: Build and Push
|
|
88
|
-
|
|
89
|
-
on:
|
|
90
27
|
push:
|
|
91
|
-
branches: [
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
env:
|
|
95
|
-
REGISTRY: ghcr.io
|
|
96
|
-
IMAGE_NAME: ${{ github.repository }}
|
|
97
|
-
|
|
98
|
-
jobs:
|
|
99
|
-
build:
|
|
100
|
-
runs-on: ubuntu-latest
|
|
101
|
-
permissions:
|
|
102
|
-
contents: read
|
|
103
|
-
packages: write
|
|
104
|
-
|
|
105
|
-
steps:
|
|
106
|
-
- uses: actions/checkout@v4
|
|
107
|
-
|
|
108
|
-
- name: Log in to Container Registry
|
|
109
|
-
uses: docker/login-action@v3
|
|
110
|
-
with:
|
|
111
|
-
registry: ${{ env.REGISTRY }}
|
|
112
|
-
username: ${{ github.actor }}
|
|
113
|
-
password: ${{ secrets.GITHUB_TOKEN }}
|
|
114
|
-
|
|
115
|
-
- name: Extract metadata
|
|
116
|
-
id: meta
|
|
117
|
-
uses: docker/metadata-action@v5
|
|
118
|
-
with:
|
|
119
|
-
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
120
|
-
tags: |
|
|
121
|
-
type=ref,event=branch
|
|
122
|
-
type=ref,event=pr
|
|
123
|
-
type=semver,pattern={{version}}
|
|
124
|
-
type=semver,pattern={{major}}.{{minor}}
|
|
125
|
-
|
|
126
|
-
- name: Build and push
|
|
127
|
-
uses: docker/build-push-action@v5
|
|
128
|
-
with:
|
|
129
|
-
context: .
|
|
130
|
-
push: true
|
|
131
|
-
tags: ${{ steps.meta.outputs.tags }}
|
|
132
|
-
labels: ${{ steps.meta.outputs.labels }}
|
|
133
|
-
cache-from: type=gha
|
|
134
|
-
cache-to: type=gha,mode=max
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
**Reference:** See `assets/deploy-workflow.yml`
|
|
138
|
-
|
|
139
|
-
### Pattern 3: Deploy to Kubernetes
|
|
140
|
-
|
|
141
|
-
```yaml
|
|
142
|
-
name: Deploy to Kubernetes
|
|
143
|
-
|
|
144
|
-
on:
|
|
145
|
-
push:
|
|
146
|
-
branches: [ main ]
|
|
147
|
-
|
|
148
|
-
jobs:
|
|
149
|
-
deploy:
|
|
150
|
-
runs-on: ubuntu-latest
|
|
151
|
-
|
|
152
|
-
steps:
|
|
153
|
-
- uses: actions/checkout@v4
|
|
154
|
-
|
|
155
|
-
- name: Configure AWS credentials
|
|
156
|
-
uses: aws-actions/configure-aws-credentials@v4
|
|
157
|
-
with:
|
|
158
|
-
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
159
|
-
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
160
|
-
aws-region: us-west-2
|
|
161
|
-
|
|
162
|
-
- name: Update kubeconfig
|
|
163
|
-
run: |
|
|
164
|
-
aws eks update-kubeconfig --name production-cluster --region us-west-2
|
|
165
|
-
|
|
166
|
-
- name: Deploy to Kubernetes
|
|
167
|
-
run: |
|
|
168
|
-
kubectl apply -f k8s/
|
|
169
|
-
kubectl rollout status deployment/my-app -n production
|
|
170
|
-
kubectl get services -n production
|
|
171
|
-
|
|
172
|
-
- name: Verify deployment
|
|
173
|
-
run: |
|
|
174
|
-
kubectl get pods -n production
|
|
175
|
-
kubectl describe deployment my-app -n production
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Pattern 4: Matrix Build
|
|
179
|
-
|
|
180
|
-
```yaml
|
|
181
|
-
name: Matrix Build
|
|
182
|
-
|
|
183
|
-
on: [push, pull_request]
|
|
184
|
-
|
|
185
|
-
jobs:
|
|
186
|
-
build:
|
|
187
|
-
runs-on: ${{ matrix.os }}
|
|
188
|
-
|
|
189
|
-
strategy:
|
|
190
|
-
matrix:
|
|
191
|
-
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
192
|
-
python-version: ['3.9', '3.10', '3.11', '3.12']
|
|
193
|
-
|
|
194
|
-
steps:
|
|
195
|
-
- uses: actions/checkout@v4
|
|
196
|
-
|
|
197
|
-
- name: Set up Python
|
|
198
|
-
uses: actions/setup-python@v5
|
|
199
|
-
with:
|
|
200
|
-
python-version: ${{ matrix.python-version }}
|
|
201
|
-
|
|
202
|
-
- name: Install dependencies
|
|
203
|
-
run: |
|
|
204
|
-
python -m pip install --upgrade pip
|
|
205
|
-
pip install -r requirements.txt
|
|
206
|
-
|
|
207
|
-
- name: Run tests
|
|
208
|
-
run: pytest
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
**Reference:** See `assets/matrix-build.yml`
|
|
212
|
-
|
|
213
|
-
## Workflow Best Practices
|
|
214
|
-
|
|
215
|
-
1. **Use specific action versions** (@v4, not @latest)
|
|
216
|
-
2. **Cache dependencies** to speed up builds
|
|
217
|
-
3. **Use secrets** for sensitive data
|
|
218
|
-
4. **Implement status checks** on PRs
|
|
219
|
-
5. **Use matrix builds** for multi-version testing
|
|
220
|
-
6. **Set appropriate permissions**
|
|
221
|
-
7. **Use reusable workflows** for common patterns
|
|
222
|
-
8. **Implement approval gates** for production
|
|
223
|
-
9. **Add notification steps** for failures
|
|
224
|
-
10. **Use self-hosted runners** for sensitive workloads
|
|
225
|
-
|
|
226
|
-
## Reusable Workflows
|
|
227
|
-
|
|
228
|
-
```yaml
|
|
229
|
-
# .github/workflows/reusable-test.yml
|
|
230
|
-
name: Reusable Test Workflow
|
|
231
|
-
|
|
232
|
-
on:
|
|
233
|
-
workflow_call:
|
|
234
|
-
inputs:
|
|
235
|
-
node-version:
|
|
236
|
-
required: true
|
|
237
|
-
type: string
|
|
238
|
-
secrets:
|
|
239
|
-
NPM_TOKEN:
|
|
240
|
-
required: true
|
|
241
|
-
|
|
28
|
+
branches: [main]
|
|
29
|
+
permissions:
|
|
30
|
+
contents: read
|
|
242
31
|
jobs:
|
|
243
32
|
test:
|
|
244
33
|
runs-on: ubuntu-latest
|
|
34
|
+
timeout-minutes: 15
|
|
245
35
|
steps:
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
36
|
+
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
|
|
37
|
+
with:
|
|
38
|
+
persist-credentials: false
|
|
39
|
+
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444
|
|
40
|
+
with:
|
|
41
|
+
node-version: '22'
|
|
42
|
+
cache: npm
|
|
43
|
+
- run: npm ci
|
|
44
|
+
- run: npm test
|
|
252
45
|
```
|
|
253
46
|
|
|
254
|
-
|
|
255
|
-
```yaml
|
|
256
|
-
jobs:
|
|
257
|
-
call-test:
|
|
258
|
-
uses: ./.github/workflows/reusable-test.yml
|
|
259
|
-
with:
|
|
260
|
-
node-version: '20.x'
|
|
261
|
-
secrets:
|
|
262
|
-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
263
|
-
```
|
|
47
|
+
## Matrix Builds
|
|
264
48
|
|
|
265
|
-
|
|
49
|
+
Add a matrix only for versions and operating systems the project supports. Keep dependencies reproducible, identify failing combinations, and avoid hiding failures with blanket continue-on-error. Test required-check behavior when jobs are conditionally skipped.
|
|
266
50
|
|
|
267
|
-
|
|
268
|
-
name: Security Scan
|
|
51
|
+
## Build and Publication
|
|
269
52
|
|
|
270
|
-
|
|
271
|
-
push:
|
|
272
|
-
branches: [ main ]
|
|
273
|
-
pull_request:
|
|
274
|
-
branches: [ main ]
|
|
53
|
+
Build an artifact from the tested commit and record its identity. Publication needs a separate trusted job with the minimum registry permission. Do not publish artifacts produced by arbitrary untrusted code in a privileged context; bind accepted artifacts to their exact source and producing workflow.
|
|
275
54
|
|
|
276
|
-
|
|
277
|
-
security:
|
|
278
|
-
runs-on: ubuntu-latest
|
|
55
|
+
## Deployment
|
|
279
56
|
|
|
280
|
-
|
|
281
|
-
- uses: actions/checkout@v4
|
|
282
|
-
|
|
283
|
-
- name: Run Trivy vulnerability scanner
|
|
284
|
-
uses: aquasecurity/trivy-action@master
|
|
285
|
-
with:
|
|
286
|
-
scan-type: 'fs'
|
|
287
|
-
scan-ref: '.'
|
|
288
|
-
format: 'sarif'
|
|
289
|
-
output: 'trivy-results.sarif'
|
|
57
|
+
Use the project's protected release path. Identify the immutable artifact, destination, workload identity, rollout and rollback checks before adding deployment commands. A named GitHub environment does not configure reviewers automatically. Verify its actual protections. Do not label a placeholder echo command as a successful deployment.
|
|
290
58
|
|
|
291
|
-
|
|
292
|
-
uses: github/codeql-action/upload-sarif@v2
|
|
293
|
-
with:
|
|
294
|
-
sarif_file: 'trivy-results.sarif'
|
|
59
|
+
## Verification
|
|
295
60
|
|
|
296
|
-
|
|
297
|
-
uses: snyk/actions/node@master
|
|
298
|
-
env:
|
|
299
|
-
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
|
300
|
-
```
|
|
61
|
+
Exercise one passing change and one deliberate test failure on a topic branch. Confirm the failing check prevents downstream publication. Inspect tokens, runner isolation, caches and artifact boundaries. Keep production credentials absent from untrusted validation jobs.
|
|
301
62
|
|
|
302
|
-
##
|
|
63
|
+
## Example
|
|
303
64
|
|
|
304
|
-
|
|
305
|
-
name: Deploy to Production
|
|
65
|
+
A project needs Linux and Windows tests. Select its supported runtime, add the two runner combinations and confirm that either failure blocks the required result. Prepare publication separately; do not add registry credentials to the matrix.
|
|
306
66
|
|
|
307
|
-
|
|
308
|
-
push:
|
|
309
|
-
tags: [ 'v*' ]
|
|
310
|
-
|
|
311
|
-
jobs:
|
|
312
|
-
deploy:
|
|
313
|
-
runs-on: ubuntu-latest
|
|
314
|
-
environment:
|
|
315
|
-
name: production
|
|
316
|
-
url: https://app.example.com
|
|
317
|
-
|
|
318
|
-
steps:
|
|
319
|
-
- uses: actions/checkout@v4
|
|
320
|
-
|
|
321
|
-
- name: Deploy application
|
|
322
|
-
run: |
|
|
323
|
-
echo "Deploying to production..."
|
|
324
|
-
# Deployment commands here
|
|
325
|
-
|
|
326
|
-
- name: Notify Slack
|
|
327
|
-
if: success()
|
|
328
|
-
uses: slackapi/slack-github-action@v1
|
|
329
|
-
with:
|
|
330
|
-
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
|
|
331
|
-
payload: |
|
|
332
|
-
{
|
|
333
|
-
"text": "Deployment to production completed successfully!"
|
|
334
|
-
}
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
## Reference Files
|
|
338
|
-
|
|
339
|
-
- `assets/test-workflow.yml` - Testing workflow template
|
|
340
|
-
- `assets/deploy-workflow.yml` - Deployment workflow template
|
|
341
|
-
- `assets/matrix-build.yml` - Matrix build template
|
|
342
|
-
- `references/common-workflows.md` - Common workflow patterns
|
|
67
|
+
## Limitations
|
|
343
68
|
|
|
344
|
-
|
|
69
|
+
This skill supplies patterns, not an installed deployment program. Repository policy, runner trust and environment settings must be inspected. Review every third-party action at its full commit SHA and treat logs and uploaded artifacts as possible data-exposure paths.
|
|
345
70
|
|
|
346
|
-
|
|
347
|
-
- `deployment-pipeline-design` - For pipeline architecture
|
|
348
|
-
- `secrets-management` - For secrets handling
|
|
71
|
+
## Sources
|
|
349
72
|
|
|
350
|
-
|
|
351
|
-
- Use this skill only when the task clearly matches the scope described above.
|
|
352
|
-
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
|
|
353
|
-
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.
|
|
73
|
+
- [GitHub secure workflow guidance](https://docs.github.com/en/actions/reference/security/secure-use)
|