Skip to main content

make-github-actions-workflow

Create GitHub Actions workflows for CI, automation, or PR management. Use when asked to create, scaffold, or add a GitHub Actions workflow (.yml file under .github/workflows/).

Datos de origen

Repositorio
dotnet/efcore
Última actividad en el origen
8 de octubre de 2026 a las 18:29
Idioma detectado de SKILL.md
inglés
Estrellas
14.798
Forks
3437

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
make-github-actions-workflow
description
Create GitHub Actions workflows for CI, automation, or PR management. Use when asked to create, scaffold, or add a GitHub Actions workflow (.yml file under .github/workflows/).
# Create GitHub Actions Workflow Create and configure GitHub Actions workflows that follow this repository's conventions and patterns. Workflows automate tasks like CI validation, PR management, issue labeling, and notifications. ## Repository Conventions This repository uses specific patterns across all workflows. Follow these conventions when creating new workflows: ### File Location and Naming - All workflows live in `.github/workflows/` - Use kebab-case names: `label-and-milestone-issues.yml`, `validate-pr-target-branch.yml` - Start with a descriptive comment block explaining the workflow's purpose ### Runner - Use `ubuntu-latest` for general-purpose jobs - Use `ubuntu-24.04` when a specific OS version is needed (e.g., copilot setup steps) ### Permissions - **Always** declare explicit permissions — never rely on defaults - Use **minimal permissions**: only request what the workflow needs - Common patterns: - Read-only: `permissions: {}` - PR comments: `pull-requests: write` - Issue management: `issues: write` - Code read: `contents: read` - For workflows that need write access to PRs from external contributors, use `pull_request_target` instead of `pull_request` - **Security warning:** `pull_request_target` workflows run in the base repository context with its permissions. Do **not** check out or execute code from the PR branch in these workflows. Instead, use the event payload and/or GitHub API (`actions/github-script`, `github.rest.*`, etc.) to inspect and act on the PR safely. ### Scripting - Use `actions/github-script@v8` for complex logic instead of shell scripts - Write JavaScript with `async/await` — the `github` object (Octokit) and `context` are available - Use `github.rest.*` for REST API calls and `github.graphql()` for GraphQL queries - Access PR/issue data via `context.payload.pull_request`, `context.repo.owner`, `context.repo.repo` - Log with `console.log()` for debugging; use `core.setFailed()` for errors ### Error Handling - Wrap API calls in try/catch blocks - Collect errors and report at the end rather than failing on the first error - Log skipped operations with a reason ## Workflow ### Step 1: Understand the Requirements Before writing the workflow, clarify: - [ ] What event(s) should trigger it? (push, pull_request, check_suite, schedule, etc.) - [ ] What permissions are needed? - [ ] What conditions should gate execution? (author, branch, labels, etc.) - [ ] What API calls are needed? - [ ] Are there rate limiting or idempotency concerns? ### Step 2: Choose the Trigger Event | Use case | Event | Notes | |----------|-------|-------| | PR opened/updated | `pull_request` | Read-only access to PR | | PR with write access | `pull_request_target` | Can comment, label, close | | PR merged | `pull_request_target: [closed]` | Check `github.event.pull_request.merged == true` | | CI checks complete | `check_suite: [completed]` | Filter `app.slug != 'github-actions'` to skip self | | Code pushed | `push` | Filter by branches/paths | | Manual trigger | `workflow_dispatch` | Add `inputs:` for parameters | | Scheduled | `schedule` | Use cron syntax | ### Step 3: Write the Workflow Create the YAML file following this template: ```yaml # Description of what this workflow does and why. name: Descriptive Workflow Name on: <trigger_event>: types: [<event_types>] permissions: <resource>: <read|write> jobs: <job-name>: if: <guard_condition> # Optional: skip when not needed runs-on: ubuntu-latest steps: - name: Descriptive step name uses: actions/github-script@v8 with: script: | // Your logic here ``` ### Step 4: Implement Guard Conditions Add conditions to avoid unnecessary runs: - Job-level `if:` for event payload checks (e.g., `github.event.check_suite.app.slug != 'github-actions'`) - Early `return` in scripts for PR author, draft status, etc. - Idempotency checks (e.g., hidden HTML comments as tags to prevent duplicate actions) For `pull_request_target` policy workflows that react to `opened`, `edited`, and `reopened`: - On `edited`, return unless `context.payload.changes?.base` is present; title or body edits must not reapply a target-branch policy. - Check permissions for `context.actor`, not only the PR author. A maintainer may edit or reopen an external PR, and that action must use the maintainer's authority. - For `opened`, the actor and author are the same, so perform one permission lookup and reuse it for policy and labeling decisions. - Exclude automation when either the actor or author is a bot. - Encode the prohibited branch class directly (for example, `release/*`) instead of requiring a single allowed branch such as `main`. - If permission lookup fails, stop without taking a destructive action; unknown access is not evidence that the contributor is external. ### Step 5: Validate After creating the workflow: - [ ] Permissions are minimal and explicitly declared - [ ] Uses `actions/github-script@v8` for complex logic - [ ] Guard conditions prevent unnecessary runs - [ ] API calls handle pagination where needed (use `per_page: 100`) - [ ] Error handling doesn't silently swallow failures - [ ] No secrets or tokens are hardcoded - [ ] Workflow doesn't create infinite loops (e.g., a workflow that triggers itself) ## Existing Workflows in This Repository Study these workflows as reference: | Workflow | Trigger | Purpose | |----------|---------|---------| | `validate-pr-target-branch.yml` | `pull_request_target: [opened, edited, reopened]` | Closes external PRs targeting release branches, adds community labels | | `label-and-milestone-issues.yml` | `pull_request_target: [closed]` | Labels and milestones issues when their fixing PR is merged | | `copilot-setup-steps.yml` | `workflow_dispatch`, `push`, `pull_request` | Sets up the development environment for Copilot | | `inter-branch-merge-flow.yml` | `push` to `release/**` | Triggers inter-branch merge via arcade | ## Common Patterns ### Commenting on a PR ```javascript await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body: 'Comment text' }); ``` ### Checking User Permissions ```javascript const { data: permissions } = await github.rest.repos.getCollaboratorPermissionLevel({ owner: context.repo.owner, repo: context.repo.repo, username: context.actor }); const hasWriteAccess = ['admin', 'write'].includes(permissions.permission); ``` ### Updating Bot-Owned Comments Idempotently A hidden marker identifies the workflow's comment but does not establish ownership: contributors can place the same marker in their own comments. Match the marker only on a bot-authored comment, then update that comment or create a new one. Preserve the workflow's pinned action SHA and never execute code from a pull-request fork in a `pull_request_target` job. ```javascript const marker = '<!-- validate-pr-target-branch -->'; const comments = await github.paginate(github.rest.issues.listComments, { owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, per_page: 100 }); const body = `${marker}\nComment text`; const existing = comments.find(comment => comment.user?.type === 'Bot' && comment.body?.includes(marker)); if (existing) { await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body }); } else { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body }); } ``` ### Reading Repository Files at a Specific Commit ```javascript const { data: fileData } = await github.rest.repos.getContent({ owner, repo, path: 'eng/Versions.props', ref: commitSha }); const content = Buffer.from(fileData.content, 'base64').toString('utf-8'); ``` ## References - [GitHub Actions documentation](https://docs.github.com/en/actions) - [Workflow syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions) - [Events that trigger workflows](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows) - [actions/github-script](https://github.com/actions/github-script)
Ver en GitHub