What you can export from GitHub Actions, and what you cannot
If you face a renewal, a pricing change or a residency requirement, the answer is that workflow definitions, run logs and artifacts can leave GitHub Actions through documented paths, but secret values cannot. Plan the migration around that split: the YAML is already portable, the history is not, and the secrets must be re-created in the new system by someone who already holds the original values.
Workflow definitions are the easy part. Each workflow lives as a YAML file in the .github/workflows directory of its repository, so it leaves with any clone of that repository. Run history is different because GitHub keeps it only for a limited time. Before you cut over, pull run logs through the REST API endpoint for /repos/{owner}/{repo}/actions/runs/{run_id}/logs, where the response is a redirect to an archive whose download link expires after 1 minute, and download artifacts with gh run download. Confirm the retention period that applies to your organization and repositories, because a repository or organization setting can differ from the default.
Secrets are the hard limit. The REST API returns Actions secret names without their values, so an export of your secret inventory gives you names, scopes and owners but not the credentials themselves. Build a list of every secret a workflow references, then have the owning teams reissue each credential in the new platform. Bulk exports are also rate limited: the documented ceiling is 5,000 requests per hour for personal access tokens and 15,000 per hour for GitHub Enterprise Cloud apps, so large run histories should be pulled with a GitHub App token and scheduled across the retention window.
Which GitHub Actions data can be exported and how
This table compares each kind of GitHub Actions data with the format, method and limit that govern its export. Read it as a checklist: workflow files travel with the repository, while logs and artifacts must be pulled through the API or CLI before retention expires. The main takeaway is that the retention period is set in your repository and organization settings, so confirm it before you plan the export window.
| Data type | Format and method | Limit or constraint |
|---|---|---|
| Workflow YAML | Files in .github/workflows, exported with any clone of the repository | No API limit; leaves with the Git history |
| Run logs | Archive of log files returned by GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs as a redirect | Download link expires after 1 minute, so fetch it immediately |
| Artifacts | Downloaded with gh run download, or named artifacts with the -n option | Available only within the artifact retention period set in your settings |
| Run history metadata | Workflow run records listed through the REST API workflow runs endpoints | Shares the REST API rate limit with log and artifact requests |
| Secrets | Names only, from the REST API Actions secrets endpoints; values are never returned | Values must be re-entered in the target platform from your own records |
| Bulk export pace | Scripted requests to the REST API for many runs, logs and artifacts | 5,000 requests per hour for personal access tokens; 15,000 per hour for GitHub Enterprise Cloud apps |
| Retention settings | Log and artifact retention configured per repository and organization | Confirm your configured period in settings; export older runs before they expire |
Why secrets, environments and runner state do not leave with the data
Exporting run history and workflow files covers only part of a GitHub Actions estate. Secrets, environment configuration and runner setup live outside the repository and the API responses, so each one needs an owner and a rebuild plan before the source platform is switched off.
Secret names only, never values
The REST API for repository and organization Actions secrets returns secret names and metadata but not their values. Every secret must be re-created in the target platform by the team that owns the source system, such as a cloud account, registry or deployment key. Start an inventory of names now, then confirm with the owner that each credential can be issued again. Treat the export as a list of work, not a copy of data.
Inventory where each secret is used
A name list does not show which workflow, job or deployment consumes a secret. Record the workflow file, branch, environment and target system for every secret name, and note whether it authenticates a person, a service or a pipeline. This record shows which rebuilt credentials must be tested first and which can be retired. Without it, a missing secret usually surfaces as a failed production deployment.
Rotate values in the target platform
Because the old values cannot be read, the cleanest route is to issue new credentials in the target system and revoke the old ones after cutover. Rotation also closes the gap for any value that was shared too widely in the past. Plan the order so that deployment keys change together with the systems they unlock. Confirm with each system owner how long the old and new credentials must overlap.
Environments and variables need checking
Deployment environments, protection rules, required reviewers and Actions variables are configuration rather than run history, so they should not be assumed to move with the export. Ask GitHub support or review the current repository settings documentation to confirm what, if anything, can be exported for environments and variables. Write down each environment's approvers and branch restrictions as a checklist for the new pipeline.
Rebuild self-hosted runners
Self-hosted runner registrations, their installed tools, cached images, network routes and service accounts are not part of the export. Each runner host must be rebuilt in the target platform, with its operating system patches, container tooling and credentials handled as new configuration. Record the labels and capabilities each job relies on, since a missing label can silently route a build to the wrong machine.
Recreate hosted runner images
GitHub-hosted runner images are maintained by GitHub and cannot be copied out. Any preinstalled tool, language runtime or system package that jobs assume must be listed from the workflow steps and installed explicitly on the new runners or in a container image. Test each workflow on the target platform to find assumptions that only held on the hosted image.
The export sequence to run before the contract ends
This sequence captures everything GitHub Actions will not hand over on its own: workflow definitions, run logs and artifacts within their retention windows, and a clear list of secrets to re-create. Each step ends with a record you can check, so the target platform starts from a known inventory.
Freeze the workflow and repository inventory
Before any transfer starts, the platform owner lists every repository in scope, every workflow file under .github/workflows, the self-hosted runners, the environments and the Actions secret names per repository. Freezing means agreeing with the teams that no new repositories or workflow changes land until the export is complete, or that changes are logged and re-exported. The output is a signed-off inventory spreadsheet that every later step is checked against.
Clone every repository with its workflow files
Run a mirror clone of each repository in the inventory so that all branches, tags and the .github/workflows directory come across intact. Workflow YAML is already in the repository, so this clone is the authoritative copy of pipeline definitions. Record the commit hash of each default branch alongside the clone. Done means every repository in the inventory has a mirror and the hashes match what GitHub reports.
Schedule log and artifact pulls ahead of retention
Run history and artifacts expire under GitHub's retention settings, so pull them while they still exist, oldest runs first. Logs come from the REST API endpoint for workflow run logs, which returns a redirect to an archive whose download link expires after one minute, so the script must follow the redirect immediately. Artifacts come from the GitHub CLI command gh run download, using -n when only named artifacts are needed. Done means each run has a stored log archive and each artifact is saved under its run ID.
Batch requests across tokens to respect rate limits
GitHub's documented limit is 5,000 REST requests per hour for personal access tokens and 15,000 per hour for GitHub Enterprise Cloud apps. A bulk pull of many runs can hit the first limit quickly, so split the repositories across several tokens or use a GitHub App installation, and have the script read the rate-limit headers and pause when the budget runs low. The export log should show requests per token per hour. Done means the job completed without skipped runs caused by throttling.
Record checksums for every exported file
Generate a SHA-256 checksum for each log archive, artifact and repository mirror, and store the manifest in a location separate from the export itself. The manifest proves that files were not altered after download and gives the target platform a fixed reference for later audits. Done means the manifest lists every file and its hash, and a second person has been able to re-run the checksum command and get identical results.
Verify run counts and artifact sizes against the source
Compare the number of workflow runs, log archives and artifacts in each repository against the counts reported by GitHub at the time of export, and compare total artifact sizes against the source. Any gap must be explained, either as expired retention, cancelled runs that have no artifacts, or a failed download to retry. Done means each repository has a reconciliation row showing source counts, exported counts and the reason for any difference.
Confirm secrets are re-created in the target platform
GitHub's REST API returns Actions secret names without their values, so the export cannot carry secrets across. Ask the platform owner and each repository maintainer to re-enter every secret from the inventory into the target CI system, using values from the source of truth such as the password manager or cloud vault. Confirm each secret by running a test pipeline that uses it, not by checking that the name exists. Done means every secret name on the inventory has a passing test in the target platform and the list is signed off.
How rate limits and retention shape a bulk export of run history
The REST API rate limit sets the pace of a bulk export: 5,000 requests per hour for personal access tokens and 15,000 per hour for GitHub Enterprise Cloud apps, according to GitHub's Actions limits documentation. Each workflow run needs its own request to GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs, and each artifact needs its own download, so total request count grows with run count rather than with data size. A repository with tens of thousands of runs will take many hours of requests at the personal token rate, and the time scales with the number of runs and artifacts you calculate from your own counts, not with a figure this page can supply. Confirm the exact limit for your token type and plan in the GitHub Actions limits documentation before you set the schedule.
Log archives come back as a redirect, and the download link expires after 1 minute. The export script must therefore follow the redirect and write the archive immediately, not collect links first and download them later. Artifacts are fetched with the GitHub CLI command gh run download, which can take named artifacts with -n, so a script can filter to the artifacts you actually need. Retention is the second clock: artifacts and logs are subject to the retention settings of each repository and organization, and the default retention is set in repository settings, so check it in Managing GitHub Actions settings for a repository before you plan anything.
Plan the window by repository, starting with the oldest runs that are closest to expiry. Build an inventory of run counts and artifact sizes per repository, then sort repositories by how much history is at risk. Run the export as a scheduled job under a dedicated service account, spread over several days if the hourly budget is shared with other tooling, and log every failed or skipped run so you can retry it. Start early: a first pass reveals the real request count, the failures and the artifacts that cannot be recovered, and any gap found after retention expires cannot be closed. Record what was exported, when, and against which token so the archive can serve as evidence later.
What to plan before the GitHub renewal or termination date
Most of the export work is inventory and timing, not tooling. The items below decide what can leave GitHub Actions, what cannot, and how much history is lost if the export starts late. Confirm contract terms and notice periods with your GitHub account team, since this page does not state them.
Complete workflow and repository inventory
List every repository that contains a .github/workflows directory, every workflow file in it, and every reusable or marketplace action each workflow calls. Workflow YAML is stored in the repository, so a clone captures it, but actions pulled from other repositories and reusable workflows in other organizations need their own entry. Record which workflows run on schedules or on external events, because those stop silently when the forge changes.
Runner and host dependencies
Record which jobs run on GitHub-hosted runners and which run on self-hosted runners, including the machines, images, network access and cloud accounts those runners use. Self-hosted runners often hold credentials, certificates and tools that never appear in the repository. The target platform needs an equivalent for each of them before the first job moves.
Secrets re-creation plan
GitHub's REST API returns Actions secret names without their values, so the export cannot carry secrets to the new platform. List every secret name at the repository, environment and organization level, identify the owner of each external credential, and plan to re-issue or rotate it in the target system. Treat this as a dependency for every migrated pipeline, since a job that cannot authenticate will fail on its first run.
Retention settings still in force
Check the Actions retention settings for each repository and organization before relying on them, because the default for artifacts is 90 days and a change made by an administrator can shorten it. Logs and artifacts past retention cannot be recovered through the API. Set the export window from the oldest run you need to keep, not from the renewal date.
Dated export and API budget
Schedule the bulk export of run logs and artifacts with a written deadline and a rate budget. The REST API allows 5,000 requests per hour for personal access tokens, so large histories take many hours of paced calls and should start well before the cutoff. Log archive links expire after one minute, so the download step must run in the same job that requests the link.
Target platform and parallel run
Agree the target platform in writing before notice, whether Gitea Actions, Forgejo Actions, Woodpecker CI, Jenkins or GitLab CI/CD, and run the chosen pipelines beside GitHub for a defined period. Compare build outputs, test results and deployment effects on the same commits. Keep the GitHub workflows active until the parallel run passes, so a failed migration does not leave you without builds.
Questions teams ask before exporting GitHub Actions data
What drives the effort of exporting GitHub Actions data?
The effort scales with how much history and how many objects sit in GitHub, not with the workflow files themselves, which are already in each repository. The main drivers are the number of repositories, the volume of run history you need to keep, the total size of artifacts, and the number of secrets that must be re-created by hand. Each of these changes the number of API calls, the download time and the manual review load. Ask for a written scope that lists these counts for your organization before accepting any estimate.
Can an in-house team export GitHub Actions data without outside help?
Often yes, provided someone can script against the REST API and the GitHub CLI and has time to verify the results. The workflow YAML leaves with every clone, and logs and artifacts can be fetched with gh run download and the logs endpoint. The harder parts are bulk pacing, secrets that cannot be read back, and proving that nothing was missed before retention expires. Teams with many repositories or strict evidence requirements usually find the verification and sign-off work is what takes the most time.
How long does a GitHub Actions data export take?
Duration depends mainly on the rate limit and the volume of data. GitHub's documentation sets 5,000 REST requests per hour for personal access tokens and 15,000 per hour for GitHub Enterprise Cloud apps, so a large run history will take many hours of paced downloads spread across days if the export is throttled. Log download links expire after 1 minute, so each file must be fetched promptly after the redirect is issued. Timing is also set by the retention window: GitHub Actions defaults to 90 days for artifacts, so any run older than that may already be gone. Confirm your organization's retention settings before planning.
What does the team need to provide for the export?
Plan for three inputs. First, an account with sufficient repository and Actions permissions, and a token that stays within the rate limits you plan around. Second, a named owner for every secret, because GitHub's REST API returns Actions secret names without values, so each value must be retrieved from the system that originally issued it and re-entered on the new platform. Third, a sign-off step where someone checks run counts, artifact counts and sample downloads against the source before the old platform is switched off. Write these owners and approvals into the scope before work starts.
Why can't secrets be exported from GitHub Actions?
GitHub does not return secret values through its API, so a migration cannot copy them. The REST API lists secret names only, which means the export inventory tells you what to recreate but not the values themselves. Treat each secret as a fresh credential: confirm the owner, issue a new value where possible, and rotate anything that has been shared widely. Hosted CI incidents, such as the CircleCI incident report of January 4, 2023, are a reason to rotate rather than copy values when you move.
Is a consultant or implementation partner worth engaging for this export?
It depends on scope. A small organization with a few repositories and short retention may manage in-house. Larger estates, regulated evidence requirements, or many secrets and artifacts usually benefit from a planned, scripted export with verification. DeployOpen plans, implements and documents self-hosted platforms in your own infrastructure and prepares evidence for compliance assessments, but it does not issue audit reports or certifications. Engagements are typically fixed-scope with agreed deliverables in writing, and a quote follows from that written scope. Ask any provider for the inventory method, the verification steps and the handover documents before comparing costs.
What should be kept as evidence after the export?
Keep the workflow files from the repository history, a manifest of exported runs and artifacts with checksums, the secret inventory with owners and rotation records, and the verification sign-off. These records show what existed, what was moved, and what was intentionally re-created. Keep them under the same access controls as the source data, because logs and artifacts can contain sensitive build output. Confirm with your auditor or compliance lead which records they expect before the export begins.
How to verify that the export is complete
Verification is the step that proves the export is usable before anyone turns off GitHub Actions or lets run history expire. Start with counts: compare the number of workflow files in the repository's .github/workflows directory with the workflows your export tooling reports, then compare the total number of workflow runs and artifacts reported by the REST API for each repository with the number your target archive holds. Record the source counts with the date and time you took them, because runs keep arriving until you disable workflows. Where counts differ, the gap is usually runs that fell outside the date range you filtered, artifacts that expired during the export, or runs that were still in progress when you started.
Next, confirm that each log archive opens and that its contents match the run it came from. Download a sample of archives from the /actions/runs/{run_id}/logs endpoint, remembering that the redirect link expires after one minute, so the download must run in the same job that requests it. Check that each archive opens, that the run ID in your index matches the run ID recorded inside the archive metadata, and that the final conclusion (success, failure or cancelled) agrees with the run record. For artifacts, compare the checksum of every file retrieved with gh run download against a checksum computed at download time, and store the manifest beside the files. A checksum shows the file did not change after export, not that it was correct when GitHub produced it, so keep the manifest with the export log.
Finally, keep a signed inventory of every secret you re-create on the new platform. GitHub's API returns secret names without values, so the inventory should list the secret name, the repository or organization scope, the system that owns the credential, the person who entered it and the date of entry, with a sign-off from the owner. Store the inventory in a location the CI platform cannot write to. This record and the verification evidence belong in your own records. They show your team's work, but independent auditors and certification bodies decide what counts as sufficient evidence for any compliance assessment, so ask them early which artifacts they expect to see.
How DeployOpen scopes and delivers a GitHub Actions data export
DeployOpen plans and delivers the export as a fixed-scope engagement, with scope, deliverables and timelines agreed in writing before work starts. The work covers the workflow files, run logs, artifacts and inventory of secrets that need to leave GitHub Actions, delivered into your own infrastructure.
How we scope
- Inventory of repositories, workflow files, run history and artifacts that must be exported before retention expires
- Written list of which secrets must be re-created by owners, since the API returns names only
- Agreed export windows that respect the REST API rate limits for your token type
- Confirmation of where exported logs and artifacts will be stored and who can access them
How we build
- Export scripts using the REST API and GitHub CLI, tested against a sample of repositories first
- Handling for log archive links that expire after one minute, with automatic re-requests
- Retrieval of artifacts by name or in full, with checksums recorded for each file
- Integrity checks that compare run counts and artifact sizes against the source inventory
How we hand over
- Documented runbook covering each export step, required token permissions and rerun procedure
- Exported data in a structured layout indexed by repository, workflow and run identifier
- Inventory report listing gaps, such as secret values that could not be exported and must be re-created
- Knowledge transfer session with the team that will own the archive after the engagement ends
How we support
- Ongoing support and upgrades are available as a retainer, scoped in writing
- Continuous testing of export scripts can be added when GitHub changes its API or limits
- Retainer scope and response expectations are agreed in writing, with no price list published
- Ask for a quote built from the written scope, including what recurs and what is one-time

