- ⚠️ GitHub Actions runners are temporary, so all data vanishes unless explicitly saved.
- 🧰 Modified files must be committed and pushed in your workflow to stay in your repository.
- 🔒 The GitHub token needs specific permissions (
contents: write) to allow commits. - 📦 Use artifacts to save data not in the repo, like coverage reports, between workflow jobs.
- 🚫 Bad Git settings, ignored files, or hidden errors often cause data loss in workflows.
If you have used GitHub Actions and wondered why your changes do not show up in your repo—or why files disappear between steps—you are not alone. This is one of the most common problems developers face when automating tasks. For example, auto-formatting code or updating version numbers. This guide will explain what happens, why your data does not "save," and how to make workflows work as you expect. At Devsolus, we help developers fix workflow problems with practical answers.
GitHub Actions 101: How It Runs Workflows
GitHub Actions is a strong tool for building CI/CD pipelines right in your project repositories. But to use it well, you need to understand how the execution environment works. Each GitHub Action job runs on a clean setup called a runner.
These runners are either virtual machines or containers that GitHub starts when needed. When the job finishes, GitHub deletes the runner. This means it is "temporary." Any changes you made—such as writing logs, creating artifacts, or compiling applications—are wiped out unless you save them on purpose.
According to GitHub Docs, this clean environment makes sure builds are repeatable. Also, it prevents problems from earlier runs. This isolation helps with security and stability. But it can be a serious issue for developers who do not understand that "saving data" does not happen by default.
Key Takeaways:
- 🧹 Each new job starts with no memory of previous runs.
- 📁 Files created during the job disappear unless explicitly saved.
- 🔄 There is no automatic state transfer between jobs or workflow runs.
- 💸 GitHub offers 60 hours/month free for GitHub Actions on public repos—use it carefully!
The Misunderstanding: “Saving” Data in GitHub Actions
There is often a difference between how developers expect GitHub Actions to work and how it actually works when saving data.
When we say “save data” in GitHub Actions, we usually mean one of two things:
- 🔁 Keeping files across multiple steps or jobs in a workflow run.
- 💾 Committing file changes back into the repository so they stay there long-term.
Either way, GitHub Actions will not do this by default. Changes made to files during a workflow—say you auto-fix lint errors or compile an output—are stored only in that runner's temporary file system. They are lost the moment the runner shuts down.
If you want changes to stay across jobs—use artifacts or cache. But if you want them to be permanent in the repo—commit and push them back.
Common Issues When Saving Data Fails
There are many reasons why your GitHub workflow may fail to “save” data. Understanding them is important for making workflows that do what you expect.
🧾 No Commit Step
You updated a file but never committed or pushed it. This is by far the most common mistake.
🔐 Missing Git Identity Setup
Git needs a configured user name and email address. Without them, Git will not make commits.
🔑 GitHub Token Problems
The GITHUB_TOKEN used to let push actions happen needs the right permissions—usually contents: write. Otherwise, your push will fail without you knowing.
📂 Files Ignored by .gitignore
You made the files, but .gitignore told Git to ignore them. Oops! Common examples include dist folders, logs, and temporary outputs.
💡 Wrong Working Directory
Sometimes, scripts or third-party actions silently change the working directory. This causes files to be written outside the actual repo tree. Git will not see changes outside the repo.
🛑 Hidden Errors
Git errors do not always stop your workflow. git commit might fail, and you would never know unless you check the output. Always check your job logs!
Fix #1: Commit Back to the Repository Correctly
To save changes to your GitHub repository, your GitHub workflow must include a commit and push step. Here is a step-by-step breakdown in a code example you can reuse:
- name: Commit changes
run: |
git config --global user.email "ci@example.com"
git config --global user.name "GitHub Action"
git add .
git diff --quiet && echo "No changes to commit" || git commit -m "Auto-update from GitHub Actions"
git push
Explanation:
git configsets the needed user identity.git add .prepares all file changes.git diff --quietchecks if anything changed. If so, commit.git pushsends it to the repository.
Make sure your workflow includes the checkout action to pull down your repo:
- uses: actions/checkout@v3
Fix #2: Check .gitignore and Exclusion Rules
It is easy to miss that .gitignore files (and sometimes global Git config) can exclude the very data you want to save.
What to Check:
- Your local
.gitignorefile in the root of your repository. .git/info/exclude, a lesser-known ignore file.- Global Git ignore config (
~/.gitignore_global) that might be used silently.
How to Verify:
Run git status locally. Make sure your generated files are listed under “Changes not staged for commit.” If not, Git is ignoring them.
If you use third-party GitHub Actions (e.g., for code generation), check their output paths. Files written outside the checked-out repository folder will not be included when you push changes.
Fix #3: Use the GitHub Token with the Right Permissions
GitHub gives a token called GITHUB_TOKEN to allow workflow operations. It is added to every GitHub Actions run. But unlike Personal Access Tokens (PATs), its permissions are limited—and restricted by default.
Required Fix:
Add permissions clearly at the top level of your workflow YAML:
permissions:
contents: write
This makes sure that git push will work using the token. Without this line, your push step may fail without you knowing—especially in public repositories or when using forks.
Important Note:
If you are forking a repo and trying to push back to the original, GitHub disables token write access for security. You will need to use encrypted secrets and possibly PATs. But be careful, especially in public actions.
More info: Workflow permissions
Fix #4: Save Data Using Artifacts Instead of Commits
Sometimes keeping data does not mean committing it to the repository. Think about using GitHub Actions artifacts. Artifacts let you upload and download files across different jobs in a single workflow or even between reruns.
Use Case Examples:
- Code coverage reports
- Linter logs
- Debug data
- Build binaries
Example:
- name: Upload report
uses: actions/upload-artifact@v3
with:
name: coverage-report
path: ./coverage
Once uploaded, you will see “Artifacts” on the workflow run’s detail page where you can manually download them. They are great for temporary data, keeping your repo clean.
For more details, see GitHub’s artifact documentation.
Best Practices for Saving or Keeping Data
Here is how to write smarter GitHub workflows that keep data well without filling up your repo:
- 📦 Use artifacts for large or temporary files that do not belong in version control.
- 🌿 Use a separate branch like
automation-updatesto store automated commits. - 🔄 Stop infinite CI loops by using
[skip ci]or checking commit messages. - 🎛 Use filtered workflow triggers (
on.push.branches-ignore) to limit automation. - 🧹 Squash automated commits later to keep your commit history clean.
Here is a quick way to stop CI loops:
git commit -m "Auto update [skip ci]"
And conditionally skipping:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
Debugging Tips
Debugging a GitHub Action is a hard problem, but here are tips to help you solve it quickly:
- Add
set -xin shell scripts—this prints each line before it runs. - Use
ls -laandpwdto confirm file locations. - Always run
git statusafter making or changing files. - Use echo statements to check logic steps like branches and conditions.
- Try act locally to simulate GitHub Actions on Docker.
Also, watch “Annotations” in the Actions tab of GitHub—they often show syntax errors, warnings, or hidden issues.
When It Is Time to Rethink Your Way to “Saving”
Not every piece of data made by CI/CD pipelines belongs in your Git repository. Ask yourself:
- 🔍 Does the output add lasting value to the repo?
- 📎 Can you get the same benefit through artifacts or GitHub comments?
- 🧼 Will this commit make my Git history messy or bloat the repo?
- 🧪 Are the generated files always the same and checkable?
If you are writing files that change often (like logs, test cases, or compiled outputs), think about keeping them out of Git. Use a remote store, object storage, or GitHub releases to save heavy data.
Real-World Use Case: Auto-Fixing with ESLint
Suppose you want to stop developers from fixing lint issues manually. Here is a helpful GitHub workflow snippet:
- name: Run ESLint
run: npx eslint . --ext .js,.ts --fix
- name: Commit ESLint fixes
run: |
git config --global user.name "Lint Bot"
git config --global user.email "lintbot@example.com"
git add .
git diff --cached --quiet || git commit -m "style: auto-fix lint issues [skip ci]"
git push
This not only auto-fixes issues but skips starting another GitHub Action, effectively closing the CI loop.
Preventing Infinite Loops and Workflow Problems
One of the worst bugs in GitHub Actions is the repeating action loop. This happens when an automation pushes a commit, which then starts the workflow again—and pushes again… forever.
How to Prevent It:
- Commit using
[skip ci]to tell workflows to ignore it. - Add conditions to your workflow to check for commit messages or actors:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
Or filter actors:
if: github.actor != 'your-bot-name'
- Use a specific branch for automation commits and exclude it via triggers:
on:
push:
branches-ignore:
- automation-updates
Bonus: Security Things to Think About for GitHub Workflows
Saving data carefully also means securing your workflows:
- 🕵️ Never
echosecrets or print them into logs. Redactions can fail. - 🔐 Use
GITHUB_TOKENinstead of personal tokens unless you truly need to. - 🔍 Use GitHub’s fine-grained permissions to give the fewest privileges—especially over write operations.
- 🔍 Limit who can start workflows through branch conditions or user filters.
- 🧪 Regularly check workflows and secrets with GitHub's built-in tools.
Solve First, Then Make Better
GitHub Actions is more than just writing working CI YAML. It is about understanding how systems think, act, and run. And it is about making smarter workflows on purpose. If your goal is to save data, be specific: are you uploading data, committing changes, or caching for reuse? Pick the right tool, and you will not only stop data loss but also lower how much work it does and cut CI costs.
At Devsolus, we believe your workflows are silent team members. Getting them right builds reliability, trust, and more work done as you grow. Whether you are auto-fixing, testing, building, or deploying—you deserve tools that save when you need them to, and clear when you do not.
Still stuck? Reach out. Let us fix your unreliable commits and debug your GitHub Actions for good.
References
GitHub Docs. (2023). GitHub Actions: Using GitHub-hosted runners
GitHub Docs. (2023). Persisting data between jobs
GitHub Docs. (2023). Workflow permissions