Migrate from GitHub Actions to Woodpecker CI

Woodpecker CI can run your builds on your own servers while repositories stay on GitHub. This page covers what moves cleanly, what needs rework, and how to sequence the cutover.

On this page

Migrate from GitHub Actions to Woodpecker CI without moving your repositories

If your builds run on GitHub Actions and you want CI in-house while your code stays on GitHub, Woodpecker CI can do that. Woodpecker connects to GitHub as a forge, so the move is about the CI engine, not Git hosting. Repositories, pull requests and branch protection stay where they are, and Woodpecker receives push, tag and pull request events from GitHub through webhooks.

The work usually falls to platform or DevOps engineers, with a security lead signing off on the secrets and the runner design. Expect a server, one or more agents running on Docker or Kubernetes, and a database that you choose for the instance (SQLite is the default, while PostgreSQL or MariaDB is recommended for larger instances). Confirm the exact server and agent setup against the Woodpecker administration documentation and your own environment before you size anything. The main effort is translating workflow jobs into container-based steps, which is mechanical for simple workflows and slower for ones built around marketplace actions.

Most of the risk sits in two places. The first is secrets: GitHub's REST API returns Actions secret names without values, so every token, deploy key and registry credential must be re-created in Woodpecker by someone who already has the original value, and that should be planned as a rotation exercise rather than a copy. The second is plugin substitution: marketplace actions have no direct equivalent, so each one needs a matching Woodpecker plugin from the plugin index or a container image you maintain, and the docs note that Drone plugins generally work but may need adjustments. Treat each substitution as a change to review, and ask your security lead to approve any image you pull from a public registry.

Which GitHub Actions capabilities map to Woodpecker CI and which need rework

This table maps each GitHub Actions capability to its Woodpecker CI equivalent and labels it clean, needs rework or gap. Read it as a checklist for pipeline translation, then confirm the rows marked for rework against your own workflows and your own secret and artifact handling before cutover.

CapabilityWoodpecker CI equivalentStatus
Workflow triggers (push, tag, pull request)Event filters on push, tag and pull_request in workflow YAML, supported on GitHub as a forgeClean
Container-based jobsEach step runs its commands inside a specified container image, so most runs-on container jobs translate directlyClean
Marketplace actionsReplaced by Woodpecker plugins (container images configured through a settings block); look up each action in the plugin indexNeeds rework
Drone pluginsGenerally work in Woodpecker, but the docs say some may need adjustmentsNeeds rework
Matrix buildsSupported through matrix configuration, though variable names and layout can differ from strategy.matrixNeeds rework
Path and branch filterswhen filters on branch, path and other conditions; confirm each path rule matches the old behaviorClean
depends_on ordering and job dependenciesMultiple workflow files in .woodpecker/ run in parallel with depends_on ordering; restructure needs: chainsNeeds rework
Services containersSupported through optional services containers in the workflow definitionClean
Artifacts and build historyNo direct equivalent to GitHub's upload-artifact; storage and retention depend on your own setup, so confirm how outputs are kept and exportedGap
SecretsRe-created in Woodpecker's secret store; GitHub never exports values, so every secret must be re-entered and confirmed in your environmentGap
Self-hosted runnersWoodpecker agents connect to the server over gRPC and run on Docker, Kubernetes or the local machineNeeds rework

What leaves GitHub, what stays behind and what to rebuild

Moving builds to Woodpecker CI while keeping code on GitHub splits the work into three groups: what you can export, what GitHub will never hand back, and what you must reconnect. Plan each group separately, because the first is documented, the second must be re-entered by hand, and the third depends on how Woodpecker authenticates to your forge.

Workflow YAML stays in the repository

Your workflow files already live in the repository under .github/workflows, so they are the first thing to inventory and the easiest to carry over. Woodpecker reads its own YAML format, so each job becomes a container-based step rather than a copy of the file. List every workflow, its triggers and every marketplace action it calls, because each one needs a Woodpecker equivalent or a rewritten command before the first build runs.

Run logs and artifacts through the API

Run logs and build artifacts can be pulled through the GitHub REST API and GitHub CLI, but only while GitHub still retains them. Under the default retention period, artifacts older than 90 days are gone, so export history in batches before you cut over. Confirm current retention settings and API rate limits in GitHub's documentation, since a bulk export of run history is limited by both.

Secrets must be re-created

GitHub's REST API returns only the names of Actions secrets, never their values, so nothing can be copied across automatically. Every repository, environment and organization secret must be re-entered in Woodpecker by someone who holds the original value. Keep a written inventory of secret names, their scopes and which pipelines use them, and rotate any credential whose value cannot be confirmed as current.

Forge webhook and repository access

Woodpecker receives push, tag and pull request events from GitHub through a webhook, and it needs its own authorized access to read repositories. Register the forge connection on the Woodpecker server, then activate each repository so the webhook is created and events flow. Check that pull request events from forks, tag builds and status reporting back to GitHub behave as they did under GitHub Actions before you switch any required checks over.

Deployment credentials and cloud trust

Deploy jobs often authenticate with long-lived cloud keys stored as secrets, or with OIDC trust relationships that GitHub issues for a workflow run. Woodpecker does not inherit GitHub's identity, so each cloud account, container registry and Kubernetes cluster must trust the new runner or receive a new credential. Review every deployment target, decide whether to issue fresh keys or set up identity federation, and test one non-production target first.

Notifications and downstream hooks

Build status, failure alerts and chat messages that GitHub Actions sent through marketplace actions or repository settings do not move with the code. Rebuild each notification as an explicit Woodpecker step or as a notification plugin, and point any deployment tool, status badge or external system that reads GitHub check results at the new source. Keep a list of every consumer of build status so none goes silent after cutover.

Migration sequence from inventory to decommissioning GitHub Actions

This sequence moves builds from GitHub Actions to self-hosted Woodpecker CI in stages, keeping the repositories on GitHub until each stage has produced verifiable evidence. Each step ends with an output that the next step depends on, so cutover happens only after a parallel run has matched the existing pipelines.

  1. Inventory workflows, secrets and marketplace actions

    Your team lists every workflow file under .github/workflows, every repository that runs Actions, every marketplace action each workflow calls, and every secret name in each repository, organization and environment. Secret values cannot be read back through the GitHub REST API, so the inventory records names and owners only. The output is a spreadsheet that maps each workflow to its triggers, its runners, its marketplace actions and the secrets it needs, with a note on who can supply each value.

  2. Map actions to container steps and plugins

    For each marketplace action in the inventory, your engineers choose a container image that runs the same commands, or a Woodpecker plugin from the plugin index, and write the replacement as a settings block in a pipeline step. Woodpecker documents that Drone plugins generally work but may need adjustments, so each plugin is tested on a throwaway branch. The output is a reviewed list of replacements, with any action that has no equivalent flagged for a custom container image.

  3. Stand up the Woodpecker server and database

    Your platform team installs the Woodpecker server, which provides the UI and API, receives forge webhooks and parses pipeline YAML. The database is chosen here: Woodpecker uses SQLite by default, and PostgreSQL or MariaDB are recommended for larger instances, so decide this before the first production data is written. Confirm the server is reachable from GitHub for webhooks, and register the GitHub forge in the server configuration. The check is a successful forge login and a test webhook delivery that the server records.

  4. Connect agents and run a pilot repository

    Start the Woodpecker agents after the server is healthy, because agents connect to the server over gRPC and take their work from it. Choose Docker, Kubernetes or the local machine as the backend for each agent pool, and apply agent labels so pipelines run only on approved hosts. Connect one low-risk pilot repository through the GitHub forge, keep its code on GitHub, and run its pipeline on pushes and pull requests. The output is a pilot pipeline that builds a commit end to end, with logs stored on your server.

  5. Run both systems against the same commits

    Keep the GitHub Actions workflows active while Woodpecker runs the translated pipelines on the same commits, so every change is built twice. Compare test results, build outputs, image digests and failure reasons for each run, and record every difference in a tracking list. Secrets used by the Woodpecker pipelines are re-created from their source systems at this stage, not copied from GitHub. The check is an agreed list of differences, each either fixed or accepted by the owner of the pipeline.

  6. Cut over webhooks and deploy jobs

    Once the parallel run shows no unresolved differences, move each repository's build triggers to Woodpecker by enabling its pipelines and disabling the matching GitHub workflows, one repository at a time. Deploy jobs move last, after the build outputs they consume are confirmed, and any deployment credentials are re-issued under the new system. Keep a documented rollback path that re-enables the GitHub workflow for each repository. The output is a dated cutover record per repository and a list of workflows still pending.

  7. Export retained artifacts and logs

    Before disabling GitHub Actions for good, export run logs and artifacts through the GitHub REST API or GitHub CLI, because GitHub Actions keeps artifacts for a limited period by default and retention settings can change. Store the exports in your own archive with the commit and run identifiers so auditors can trace a build later. Confirm the archive can be read by someone outside the migration team. The output is an indexed archive and a retention record that names where each file lives.

  8. Decommission GitHub Actions runners and settings

    Remove self-hosted GitHub Actions runners from every host, revoke their registration tokens, and disable Actions in repositories that no longer use it, using the repository Actions settings in GitHub. Delete the secrets that were copied into Woodpecker from GitHub, and rotate any credential whose value was ever shared outside its owner. The check is a list of hosts with no runner process, a list of repositories with Actions disabled, and a signed-off record from the security owner.

How Woodpecker's server and agents replace GitHub-hosted runners

A Woodpecker installation splits the work that GitHub-hosted runners do for you into two roles you operate. The server provides the UI and API, receives forge webhooks from GitHub and parses the pipeline YAML. Agents run the workflows and connect back to the server over gRPC, so the agents must be able to reach the server's gRPC port, and the server must be able to reach GitHub's webhook delivery path. An optional autoscaler can create cloud VMs for pending builds, which is the closest equivalent to GitHub's hosted runner pool, but it is optional and adds its own cloud account, image and cost decisions. Before you migrate, confirm which of these paths your network policy allows and which secrets the agents will hold. Agents execute steps through a backend, and the choice changes your storage and network assumptions. Docker and the local machine backends run each step in a container on a host you manage. The Kubernetes backend runs each step in its own pod and creates a temporary persistent volume claim for the pipeline, which is 10G and ReadWriteMany by default, so files can pass between steps. Check that your cluster has a storage class that supports ReadWriteMany, that the 10G default fits your largest checkout and build cache, and that the namespace's quotas and network policies allow pods to reach the server and your registries. Confirm these defaults against the current Kubernetes backend documentation before you size the volume.

Plan for the operational work that hosted runners currently absorb. You own the server database (SQLite by default, with PostgreSQL or MariaDB recommended for larger instances), agent patching, capacity during peak pushes and the upgrade path for each release, so pin versions and test them in a staging instance first. Ask your platform team who will hold the agent registration secret, how agents are isolated from each other, and whether untrusted pull request builds can reach production credentials. Those answers decide whether you run one shared agent pool or separate pools for trusted and untrusted workloads. Illustrative example: a team that runs six agents on one Kubernetes cluster may find that a burst of pull request builds exhausts the shared volume or the namespace quota before CPU becomes the limit. Load test that case with your own repositories before cutting over.

What drives the cost and duration of the move

This table breaks the move into the cost components a Woodpecker migration creates and the drivers that raise or lower each one. Read each row as a question to put to a fixed-scope quote: who is paid for the work, whether it recurs, and what you can change to keep it down. No durations are given here because they depend on the scope agreed in writing.

Driver or componentWhy it changes cost or effortHow to keep it down
Platform hosting and storageWoodpecker runs a server, agents and a database (SQLite by default, PostgreSQL or MariaDB recommended for larger instances). Hosting, storage and backups recur every month once builds run in-house.Size the server and database to the number of active repositories, set build log retention deliberately, and ask the quote to name the hosting target.
Agent capacity and autoscalingAgents run workflows on Docker, Kubernetes or the local machine, and the optional autoscaler creates cloud VMs for pending builds. Peak concurrency sets how many agents you pay to run.Measure queue wait times on your current GitHub Actions usage, then size a baseline pool and add autoscaling for bursts instead of provisioning for peak.
Number of repositoriesEach repository needs its forge connection, webhook, secrets and a translated pipeline. Repository count drives the volume of pipeline conversion and testing.Migrate in waves by team or service, retire unused repositories first, and ask for per-repository effort in the quote.
Marketplace actions in useEach GitHub Action used in a workflow must be matched to a Woodpecker plugin or rewritten as container commands. Plugins generally work but can need adjustment, so every action is a small engineering task.Inventory every uses: reference across workflows, group duplicates, and prefer shell commands in standard container images for simple actions.
Deployment targetsDeploy steps carry credentials, cluster access and approval logic. Each target needs its own plugin or script, its own test run and its own rollback check.Limit the first migration to build and test, move deployments in a later phase, and confirm which targets the quote covers.
Secret re-creationGitHub's API returns secret names without values, so every secret must be sourced again from its owner and entered into Woodpecker. Rotation is often needed at the same time.Keep a register of secret names and owners before the move, and ask for a step that rotates credentials as they are re-entered.
Self-hosted runner countEach GitHub self-hosted runner has a Woodpecker agent equivalent to build, patch and monitor. Runner count multiplies the operating work and the hardening work.Consolidate runners onto fewer, labeled agents where workloads allow, and confirm agent labels are enforced on your server version.
Compliance evidence needsAssessors may ask for records of who changed pipelines, how secrets were handled and how builds were approved. Preparing those controls and evidence takes review time, and DeployOpen prepares evidence but does not issue audit reports.Agree the control set before work starts, collect evidence during the migration rather than afterwards, and confirm with your auditor which records they will accept.
Security review and hardeningSelf-hosted CI runs builds with access to your code and deployment credentials. Review covers the forge webhook, agent isolation, plugin trust and the server's access controls.Pin plugin images, restrict which projects can use privileged settings, and include the review in the written scope.
Ongoing upgrades to Woodpecker releasesWoodpecker releases change behavior, for example 3.19.0 fixed an injection of matrix environment variables into the default clone step. Each upgrade needs testing against your pipelines.Keep a staging server, read release notes before each upgrade, and decide in the quote whether upgrades and testing are included or run as a retainer.

What usually goes wrong when CI moves to Woodpecker

Most failed CI migrations break in the same few places: secrets that did not arrive, workflows that quietly changed meaning, history that expired, and a new server nobody maintains. The cards below pair each risk with a check to run before cutover, so the team can catch it in a staging pipeline instead of in production.

Secrets that must be re-created

GitHub's REST API returns Actions secret names without their values, so nothing can be copied across automatically. Treat every deployment token, registry password and signing key as compromised for migration purposes and issue new credentials at the source. Rotate them at the same time, then store them in Woodpecker's secret store scoped to the specific repositories that need them. Keep an inventory of each secret, its owner and the step that consumes it.

Marketplace actions replaced by plugins

Many GitHub workflows call marketplace actions pinned to a tag or commit that Woodpecker does not run. Each one needs a replacement, either a plugin from the Woodpecker plugin index or a plain container step with the same commands. Plugins are container images with their own settings block and default behavior, and the Woodpecker documentation notes that Drone plugins generally work but may need adjustments. Pin each replacement to a specific image version and run it against a test repository before relying on its output.

GitHub context variables that no longer resolve

Workflows often read values such as the GitHub token, the event payload, the actor or the ref through expressions that have no equivalent in Woodpecker. Steps that depend on these values can run without error and still deploy the wrong branch or tag. Search every workflow for expression contexts, then map each one to a Woodpecker environment variable or a when filter on event, branch or tag. Test pull request and tag events separately, because filters behave differently per event.

Artifact history lost at retention end

GitHub Actions keeps artifacts for 90 days by default, so any build older than that is gone from the hosted service. Moving to Woodpecker does not recover them, and the old run logs and release evidence disappear on the same schedule. Export the artifacts and logs that auditors, release managers or incident responders may need before the old service is switched off. Store them in your own object storage with a documented retention rule, and record where each release's build output now lives.

Agents running without authentication

A Woodpecker agent connects to the server over gRPC, so an agent that is reachable or enrolled with a weak shared secret can receive pipeline work it should never see. Run agents on dedicated hosts or Kubernetes namespaces, keep them off the public network, and limit each agent to the labels for its own projects. Confirm the agent secret is unique per installation and rotated on a schedule. Review which agents can run privileged container steps, since those steps can reach the host.

Single server without backup or upgrades

A default Woodpecker installation uses SQLite, which is suitable for small setups but turns the server database into a single point of failure. Teams that move production builds often run one server with no tested backup, no upgrade plan and no record of the configuration. Move the database to PostgreSQL or MariaDB for larger instances, back it up and test a restore, and pin the Woodpecker release. Plan upgrades against the release notes, since the project publishes fixes such as enforcing agent labels on the server in version 3.19.0.

How the move differs by team size and starting point

A small team with a few repositories and simple builds usually has one or two pipeline files, a handful of marketplace actions and a short list of secrets. The move is mostly about standing up one Woodpecker server, connecting it to GitHub as the forge and rewriting each workflow as container-based steps. Because the repositories stay on GitHub, nothing about code review changes for developers.

  • Connection: Woodpecker reads GitHub push, tag and pull request events, so developers keep their current branch and review habits.
  • Translation: Each job becomes a step that runs in a named container image, which is often the largest edit per workflow.
  • Actions: Marketplace actions are replaced with Woodpecker plugins from the plugin index or with plain shell commands.
  • Secrets: Values must be entered again by someone with access to the source system, since GitHub never returns them.
  • Operations: One server and one or more agents are the whole footprint, which keeps the recurring work small.

Before cutover, confirm which hosting model you will run and who will patch the server and agents after go-live.

Questions teams ask before moving GitHub Actions to Woodpecker CI

How much does moving from GitHub Actions to Woodpecker CI cost?

Woodpecker CI is Apache-2.0 licensed, so the software itself has no license fee. The cost is the infrastructure and people: servers or a Kubernetes cluster for the server and agents, database hosting, storage for logs and artifacts, and the engineering time to convert workflows, plugins and secrets. Infrastructure recurs every month, while conversion and cutover are largely one-time. Costs rise with the number of repositories, the number of pipelines per repository, build concurrency and the amount of artifact storage you keep. Ask any provider for a quote that lists each component separately, including who maintains upgrades and on-call coverage after cutover.

How long does a migration to Woodpecker CI take?

Duration depends on how many repositories and workflows you have, how many use marketplace actions or matrix builds, and whether you also change deployment steps. No researched duration applies to your estimate, so confirm timelines against your own inventory. Teams usually shorten the work by grouping repositories into waves, converting the simplest pipelines first and running old and new pipelines in parallel until results match. Expect longer timelines when secrets must be re-created by owners who are hard to reach, or when a Kubernetes backend and persistent storage need design work.

What does the team need to provide for the migration?

The team needs an inventory of repositories and workflows, a list of every GitHub Actions marketplace action in use, and the owners of each secret and environment. You also need a place to host the Woodpecker server and agents, a database such as PostgreSQL or MariaDB for larger instances, and a GitHub OAuth application or equivalent forge credentials. Someone must own the container images used by steps, the plugin choices and the release process for the platform itself. Confirm these items with your security team before work starts, because they decide who can approve access to production secrets.

Can our engineers do this migration in-house?

Often yes, if at least one engineer knows containers, YAML pipelines and your deployment targets, and someone can run the server and agents after go-live. Woodpecker workflows are YAML files and steps run in container images, so the conversion itself is familiar work. The harder parts are the operations: upgrades, backups, agent capacity, and the security of the server that holds deployment access. Decide early whether your team will carry that operational load for the long term. A fixed-scope engagement with DeployOpen can cover planning, implementation, hardening, backup and documentation, with ongoing support available as a retainer.

Do our repositories have to leave GitHub?

No. Woodpecker CI connects to GitHub as a forge and supports push, tag and pull request events, so you can keep code, pull requests and reviews on GitHub while builds run on your own infrastructure. Connecting multiple forges to one Woodpecker server is still experimental according to the forge documentation, so plan for a single forge per server. Moving the repositories themselves is a separate project with its own cost and risk, and you can defer it.

How are secrets and build artifacts handled during the move?

Secrets cannot be exported from GitHub. The REST API returns secret names without values, so each secret must be re-created in Woodpecker from its source system, such as a vault or the owning team. Plan a rotation for any credential that may be exposed, because the source of truth often lives outside the repository. Build artifacts and logs are kept by GitHub Actions for a limited period, with 90 days as the default according to GitHub's documentation, so export any history you need before retention expires. Store Woodpecker's own artifacts and logs on storage you control and set a retention policy that your compliance team has approved.

When should we hire outside help for the migration?

Consider outside help when the pipelines deploy to regulated or production environments, when secrets are numerous or hard to trace, or when your team lacks capacity to run the platform after cutover. Outside help is also useful for security testing of the CI server and agents before they handle production credentials. DeployOpen plans, implements, hardens, backs up, documents and supports self-hosted platforms in your own infrastructure, and most engagements are fixed-scope with agreed deliverables and timelines in writing before work begins. Request a written scope and quote that separates conversion, secret handling, hardening and ongoing support.

What your team must provide to keep the migration on track

The migration moves on schedule only when your team supplies the inputs before work starts, and the written scope should list each one. The first is a complete inventory of repositories and workflows: every file under .github/workflows, every marketplace action referenced, every reusable workflow, and the branch and tag filters that decide when a build runs. The second is a named owner for each secret and each deploy target, because GitHub never exports secret values and someone must be able to re-enter each credential in Woodpecker and confirm it still works. Ask GitHub organization owners to confirm which people hold admin rights so access can be granted for the forge connection and webhooks.

The third input is infrastructure. Your team provides the host or Kubernetes namespace for the Woodpecker server, the agents that will run steps on Docker, Kubernetes or a local machine, and the database, which is SQLite by default with PostgreSQL or MariaDB recommended for larger instances. Confirm network paths from the agents to the server and to your artifact and deploy targets, and confirm which registries the build images can pull from. Also decide whether build history and artifacts from GitHub will be kept as an archive, since GitHub's retention windows continue to run during the project.

The fourth input is sign-off on the cutover window. Agree who approves the switch of webhooks from GitHub Actions to Woodpecker, who is on call during the first week of production builds, and how a rollback to GitHub Actions is triggered. Your team also keeps the decisions on secret rotation and access policy: DeployOpen can prepare the inventory, the rotation steps and the access model, but your security owners decide which credentials are rotated, which are retired, and who may approve changes to the Woodpecker server.

How DeployOpen scopes, runs and supports the Woodpecker migration

DeployOpen plans and implements the move from GitHub Actions to self-hosted Woodpecker CI inside your own infrastructure, with the Woodpecker server, agents and secrets handling set up to your written scope. Engagements are fixed-scope, so the deliverables, timelines and responsibilities are agreed in writing before work starts.

How we scope

  • We inventory which repositories keep GitHub as the forge and which workflows, actions and secrets each one depends on.
  • The written scope lists the Woodpecker server, agent backend (Docker or Kubernetes), database and the pipelines to be translated.
  • We agree in writing how secrets will be re-created by your owners, since GitHub does not export their values.

How we build

  • We connect Woodpecker to GitHub as a forge and test push, tag and pull request events on pilot repositories.
  • We translate workflow jobs into container-based steps and map marketplace actions to Woodpecker plugins, flagging any that need adjustment.
  • We run the pipelines in parallel with existing GitHub Actions workflows and document the results before cutover.

How we hand over

  • You receive documented configuration for the server, agents, backups and upgrade steps, along with the pipeline files you approved.
  • We provide a runbook covering secret rotation, artifact retention you set yourself and how to add new repositories.
  • Knowledge transfer sessions are held with your platform and security teams before the engagement closes.

How we support

  • Ongoing support, upgrades and continuous testing of the Woodpecker installation are available as a retainer.
  • Retainer scope, response expectations and upgrade cadence are agreed in writing and confirmed against your own environment.
  • Support can cover new Woodpecker releases, so your team can review each one before it reaches production pipelines.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.