Skip to content

⚙️ GitHub Actions Generator

Pick a workflow type and triggers from a form to instantly generate YAML you can drop into .github/workflows/. Supports Node.js, Python, PHP, Go, Docker build/push, Pages, Vercel, Netlify, Release, Cron, and Lint workflows.

100% Free No signup Browser-only 5 languages Dark mode

🔒 About Privacy

Triggers
(click "Generate YAML" above)

📖 Where people get stuck

Choose a workflow type (Node, Python, PHP, Go, Docker, Pages, Vercel, Netlify, Release, Cron or Lint) and its triggers, and this generates YAML you can drop straight into .github/workflows/. Everything runs in the browser and branch names and versions are not transmitted. What it generates is a syntactically valid workflow, not a workflow that will pass in your projectthe actual commands for installing dependencies and running tests differ from repository to repository. And what really hurts in CI is not YAML formatting but permissions and time. That is what follows.

Case What happens What to do
A pull request from a fork gets no secrets A workflow triggered by pull_request runs with a read-only GITHUB_TOKEN and receives none of the repository secrets when the pull request comes from a fork. That is a deliberate safety measure — otherwise anyone could make your secrets print themselves simply by opening a pull request. The consequence is that a workflow containing a deploy or a coverage upload always fails on pull requests from forks. A dangerous workaround is well known: switching to pull_request_target does deliver the secrets, but that trigger runs with the permissions of the base branch, so checking out and running the pull request code there executes code written by an outsider with your secrets in handeffectively a repository takeover. Split the workflow in two. Run tests and lint on pull_request, which needs no secrets, and deploys on push to main or on release. Pull requests from forks then pass CI normally, and no path exists by which secrets can leave. If you do use pull_request_target, never check out the pull request coderestrict it to things that do not execute code, such as labelling or posting a comment. Alongside this, state permissions: explicitly at the top of every workflowwriting permissions: {contents: read} alone strips write access from that workflow GITHUB_TOKEN. Adding back only the permissions a given job needs is the correct order of operations.
Referencing a third-party action by tag The v1 in uses: some/action@v1 is a branch or tag, that is, a movable referenceif the action author, or whoever takes over that account, changes its contents, your CI runs different code on its next execution. That code has access to the GITHUB_TOKEN and to any secrets you passed to the job. This is not theoretical: popular actions have in fact been compromised and used to harvest secrets. Official actions/* are one thing, but casually referencing a handy little action at @main is not meaningfully different from handing someone write access to your repository. Pin third-party actions to a commit SHAuses: some/action@a1b2c3d4.... A SHA cannot be rewritten, so what runs next is determined. Leave updates to Dependabot: adding package-ecosystem: "github-actions" to .github/dependabot.yml makes it open pull requests that bump the SHA — pinning and updating are not in conflict. Reducing the number of actions is effective too: if an action only copies one file, writing cp under run: removes a dependency. And pass secrets to jobs as narrowly as possibleput them at workflow level as environment variables and every action inside can read them.
Cron does not run on time, and stops after 60 days The schedule trigger has three traps beyond its syntax. Times are always UTC, not your timezone — 0 3 * * * means three in the morning UTC. Runs are not punctual: at busy periods they are delayed by minutes to tens of minutes, and under heavy load a run can be skipped entirely. The top of the hour is the busiest slot, so simply avoiding round times makes things steadier. The third is the one that surprises people most: GitHub automatically disables scheduled workflows in a repository with no commits for 60 daysan email is sent, but if you miss it, discovering months later that nothing has run is an entirely ordinary outcome. Write the cron expression in UTC and offset it a few minutes from the round time17 3 * * * rather than 0 3 * * *. And always add workflow_dispatch alongside itbeing able to trigger it by hand is what lets you test it and re-run it (a workflow you cannot try without waiting for the schedule is itself a source of accidents). The defence against auto-disabling is to be able to notice: have the job notify an external system on success, so that the absence of a notification is detectablealerting on failure alone cannot detect a job that stopped running. If you need precise timing or high reliability, use a dedicated scheduler rather than the GitHub Actions cron.

Build cache keys together with the lockfile. If the cache: npm of actions/setup-node or the key of actions/cache does not include a hash of the lockfile, an old cache keeps being restored even after you update dependencies — producing the opaque situation where it is fixed locally but only CI fails, on stale dependencies. Put hashFiles('**/package-lock.json') in the key. Caches are also shared across branchesa poisoned cache spreads to other branches, so when in doubt, rename the key and rebuild it. One more thing: take care not to print secrets into the log. GitHub masks registered secrets automatically, but a transformed value — Base64 encoded, embedded in JSON, or partially extracted — is not masked. Enabling set -x or debug output records the whole command lineand on a public repository, anyone can read the Actions log.

📖 How to Use

  1. 1
    Pick a workflow type
    Select from Node.js, Python, PHP, Go, Docker, Pages, Vercel, Netlify, Release, Cron, or Lint.
  2. 2
    Set triggers and branch
    Toggle push, pull_request, schedule, or workflow_dispatch and enter the target branch or cron expression.
  3. 3
    Generate YAML and commit it
    Click Generate YAML, then copy or download. Drop the file under .github/workflows/ and push to enable it.

❓ Frequently Asked Questions

How do I configure the secrets it references?
If the YAML references ${{ secrets.XXX }}, add the matching secret in your repo Settings → Secrets and variables → Actions. Examples include DOCKERHUB_TOKEN, VERCEL_TOKEN, and NETLIFY_AUTH_TOKEN.
Which action versions are pinned?
It emits widely used stable versions, mainly actions/checkout@v4 and actions/setup-* v5. After generation you can pin to a commit SHA for extra reproducibility.
Can I use this with self-hosted runners?
Yes. Just change runs-on in the generated YAML to self-hosted, or to a label array such as [self-hosted, linux, x64].
🐛 Found a bug or issue with this tool?

Free to use, no signup. Even just the steps to reproduce are helpful. Reports go directly to the operator and help us fix issues.

* Browser info (UA / screen / language / URL) is sent automatically to help reproduce the issue