This GitHub Action is designed to create a zip archive of all files that have been changed in the latest commit. It works on any repository where you want to automate the process of archiving only the changed files, including those in subfolders, while excluding specific directories such as .github
.
This action does the following:
- Checks Out the Code: The action checks out your repository to access the files.
- Gets the Current Commit Hash: Retrieves the current commit hash for reference.
- Counts the Commits: If there is more than one commit, it runs a
git diff
command to list all files changed between the current commit (HEAD
) and the previous commit (HEAD^
). If there is only one commit (initial commit), it skips this step and generates an empty list of changed files. - Copies Changed Files: The action creates a new directory (
changed_files
) and copies all changed files into it, preserving the original directory structure. - Zips the Files: The copied files are then zipped into a
changed_files.zip
archive. The.github
folder is explicitly excluded from this archive. - Uploads the Zip File: The zip file is uploaded as an artifact, which can then be downloaded from the GitHub Actions tab.
- This action requires that your repository has multiple commits. For an initial commit (when there are no prior commits), no files will be archived.
To use this GitHub Action in your repository, follow these steps:
Add a workflow YAML file to the .github/workflows
directory in your repository. For example, create a file called archive-changed-files.yml
with the following content:
name: Create Zip of Changed Files
on:
push:
branches:
- main # Change this to your target branch
jobs:
zip_changed_files:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0 # Fetch all commits
- name: Print OS Information
run: echo "Running on: $(uname -a)"
- name: Get the current commit hash
id: get_commit
run: |
commitHash=$(git rev-parse HEAD)
echo "Current commit: $commitHash"
echo "::set-output name=commit::$commitHash"
- name: Get list of changed files
id: changed_files
run: |
commitCount=$(git rev-list --count HEAD)
echo "Number of commits: $commitCount"
if [ "$commitCount" -gt 1 ]; then
git diff --name-only HEAD^ HEAD > changed_files.txt
echo "Changed files:"
cat changed_files.txt
else
echo "No previous commit found. No files changed."
touch changed_files.txt
fi
- name: Copy changed files to a new directory
run: |
mkdir changed_files
while IFS= read -r file; do
if [ -f "$file" ]; then
destination="changed_files/$(dirname "$file")"
mkdir -p "$destination"
cp "$file" "$destination"
fi
done < changed_files.txt
- name: Zip the changed files
run: zip -r changed_files.zip changed_files -x "changed_files/.github/*"
- name: Upload zip file as an artifact
uses: actions/upload-artifact@v3
with:
name: changed-files
path: changed_files.zip
You can customize the workflow by:
- Branch Targeting: Change the
main
branch to any branch you want this action to run on. - File and Folder Exclusions: If you want to exclude other directories or files from being included in the zip, you can modify the
-x
parameter in the zip command.
Once the workflow file is added to your repository, it will automatically run on every push to the target branch. After the action completes, the zipped archive of changed files will be available as an artifact in the GitHub Actions tab for download.
The actions/checkout@v3
step checks out the repository’s latest state, including all files and directories. The fetch-depth: 0
option ensures that all commits are fetched so that the git diff
command works with the full commit history.
This step is optional and prints out the OS information for debugging purposes, verifying that the workflow is running on the correct environment.
This step captures the current commit hash and stores it in the workflow’s output. This hash can be useful for debugging or referencing the exact commit for the changes being processed.
This step runs a git diff
command to compare the current commit (HEAD
) with the previous commit (HEAD^
). It generates a list of files that have changed between these two commits and stores them in changed_files.txt
. If this is the first commit in the repository, it creates an empty changed_files.txt
.
This step reads the changed_files.txt
and copies each file to the changed_files
directory, preserving the directory structure. Only files (not directories) are copied.
The action zips the changed_files
directory into changed_files.zip
. The .github
directory is explicitly excluded from the zip archive using the -x
option.
The zipped file is uploaded as an artifact named changed-files. You can download this artifact from the GitHub Actions tab.
By default, the .github
directory is excluded from the zip file. If you want to exclude additional directories or specific files, you can modify the -x
option in the zip
command. For example, to exclude the docs
folder and .env
files, update the command as follows:
run: zip -r changed_files.zip changed_files -x "changed_files/.github/*" "changed_files/docs/*" "*.env"
This action is useful in scenarios where you want to:
- Archive only the files that were changed in a specific commit.
- Keep track of changes made between commits.
- Automate file archiving as part of a CI/CD pipeline.
This GitHub Action is licensed under the MIT License. Feel free to customize and use it in your projects.