Automates secure CI/CD artifact backups to Google Drive. Features per-file retention, auto-sharing, smart format conversion, and zero-config privacy.
Upload Github-Actions Artifacts TO Google Drive
Github Action To Upload Artifacts to Google Drive Using A Google Drive API.
๐บ Video Tutorial
Watch our comprehensive tutorial on how to use this action:
[!NOTE]
The video shows converting credentials to Base64 (3:27 to 5:00). you can skip this part!
You can now simply paste the plain JSON content into your GitHub Secret. Base64 is still supported but optional.
This tutorial covers:
- Setting up the Google Drive API
- Creating and configuring a service account
- Using the action in your GitHub workflow
- Handling different upload scenarios
๐ Quick Start
steps:
- uses: actions/checkout@v6
- name: Upload Artifacts TO Google Drive uses: Jumbo810/UploadGithubArtifactsTOGDrive@v2.3.5 with: target: <LOCALPATHTOYOURFILE> credentials: ${{ secrets.YOURSERVICEACCOUNT_CREDENTIALS }} parentfolderid: <YOURDRIVEFOLDER_ID>
โจ Features
- Upload files from your GitHub workflow to Google Drive
- Support for uploading multiple files using glob patterns
- Create nested folders automatically
- Option to override existing files
- Support for custom file naming
- Secure handling of Google Drive credentials
- Multiple file handling strategies (delete, update, or add new)
- Safe Per-File Retention Policy: Automatically manage version history by keeping only the N most recent versions of each specific file, ensuring unrelated files are safe.
- Share Notifications: Opt-in email alerts to notify recipients immediately when files are shared with them.
- Smart Format Conversion: Automatically convert CSV/Excel/Markdown files to native Google Docs/Sheets formats.
- Auto-Sharing: Grant immediate access to teammates via email list.
- Traceability: Inject build metadata (Commit, Branch, Run Link) into file description.
- Smart Resumable Uploads: Automatically handles large files (>5MB) with robust retry logic.
๐ง Setting Up Google Drive API
Before using this action, you need to set up the Google Drive API:
- Go to the Google Cloud Console
- Create a new project or select an existing one
- Enable the Google Drive API
- Create a service account
- Create a key for the service account (JSON format)
- Copy the content of the JSON key file.
- Store the JSON content in a GitHub Secret (e.g.,
GDRIVE_CREDENTIALS). - Create a folder in Google Drive where you want to upload artifacts, then set the share permission to "Editor" so the Github Action can upload the files to this folder using service account.
- Copy the ID of your Google Drive folder from the browser URL. When you're viewing your folder in Google Drive, the folder ID is the long string of characters that appears after 'folders/' in the URL. For example, in the URL 'https://drive.google.com/drive/folders/1AbCdEfGhIjKlMnOpQrStUvWxYz12345', the folder ID is '1AbCdEfGhIjKlMnOpQrStUvWxYz12345'. You'll need this ID for the parentfolderid parameter in your GitHub workflow.
โ ๏ธ Troubleshooting: Storage Quota Errors
If you encounter an error like The user's Drive storage quota has been exceeded, it is likely because Service Accounts have 0 GB storage by default.
Solution (For Google Workspace Users):
- Create a Shared Drive.
- Add the Service Account as a "Content Manager".
- Use the Folder ID from that Shared Drive in your workflow.
Advanced: Uploading to "My Drive" (Requires Admin Setup)
If you absolutely must upload to a personal user's drive and cannot use Shared Drives, you must use Domain-Wide Delegation.
- Enable Domain-Wide Delegation for the Service Account in Google Cloud Console.
- In Google Admin Console, authorize the Service Account's Client ID with
https://www.googleapis.com/auth/drivescope. - In your Github Action, use the
ownerinput to specify the personal email address to impersonate.
๐ Usage Examples
Upload multiple files using glob pattern:
steps:
- uses: actions/checkout@v6
- name: Upload Multiple Files TO Google Drive uses: Jumbo810/UploadGithubArtifactsTOGDrive@v2.3.5 with: target: "dist/*.zip" credentials: ${{ secrets.YOURSERVICEACCOUNT_CREDENTIALS }} parentfolderid: <YOURDRIVEFOLDER_ID>
Upload to a nested folder with custom name:
steps:
- uses: actions/checkout@v6
- name: Upload to Nested Folder with Custom Name uses: Jumbo810/UploadGithubArtifactsTOGDrive@v2.3.5 with: target: build/app.jar name: application-${{ github.sha }}.jar credentials: ${{ secrets.YOURSERVICEACCOUNT_CREDENTIALS }} parentfolderid: <YOURDRIVEFOLDER_ID> childfolder: releases/${{ github.refname }}
Upload with file override:
steps:
- uses: actions/checkout@v6
- name: Upload with Override uses: Jumbo810/UploadGithubArtifactsTOGDrive@v2.3.5 with: target: build/latest.zip credentials: ${{ secrets.YOURSERVICEACCOUNT_CREDENTIALS }} parentfolderid: <YOURDRIVEFOLDER_ID> override: true
Upload with custom ownership:
steps:
- uses: actions/checkout@v6
- name: Upload with Custom Ownership uses: Jumbo810/UploadGithubArtifactsTOGDrive@v2.3.5 with: target: build/report.pdf credentials: ${{ secrets.YOURSERVICEACCOUNT_CREDENTIALS }} parentfolderid: <YOURDRIVEFOLDER_ID> owner: user@yourdomain.com
Using different replace modes:
steps:
- uses: actions/checkout@v6
- name: Upload with Update-in-Place Strategy uses: Jumbo810/UploadGithubArtifactsTOGDrive@v2.3.5 with: target: build/latest.zip credentials: ${{ secrets.YOURSERVICEACCOUNT_CREDENTIALS }} parentfolderid: <YOURDRIVEFOLDER_ID> replacemode: updatein_place
Upload and Share with Notification:
steps:
- uses: actions/checkout@v6
- name: Upload and Share uses: Jumbo810/UploadGithubArtifactsTOGDrive@v2.3.5 with: target: build/release.zip credentials: ${{ secrets.YOURSERVICEACCOUNT_CREDENTIALS }} parentfolderid: <YOURDRIVEFOLDER_ID> share_with: "user1@example.com, user2@example.com" sendsharenotification: true
โ๏ธ Input Parameters
๐ข Basic Configuration (Required)
| Input | Description | |---|---| | target | Required. The file(s) you want to upload. Supports glob patterns (e.g., dist/*.apk). | | credentials | Required. Your Google Service Account JSON. (Paste the plain JSON content directly, or Base64 encoded string). | | parentfolderid | Required. The ID of the Google Drive folder where you want to upload. |
๐ Advanced Configuration (Optional)
Click to expand advanced options
| Input | Description | |---|---| | child_folder | Optional. Name of a subfolder to create/use inside the parent folder. | | name | Optional. Rename the file after upload (only works for single file uploads). | | override | Legacy. If true, deletes existing files with the same name before upload. (Use replace_mode instead). | | replacemode | Determines how to handle existing files. Options: deletefirst, updateinplace, or add_new (default). | | maxretentioncount | Number of most recent files with the same name to keep. Effectively applies a "Version History" policy per file. Older versions of the specific file are deleted. Set to 0 to disable (default). | | convert_files | If true, automatically converts supported files (.csv, .md, etc.) to Google Docs/Sheets. Default false. | | share_with | Comma-separated list of emails to grant "reader" access immediately after upload. | | sendsharenotification | If true, sends an email notification to the users specified in share_with. Default false. | | set_metadata | If true, adds GitHub context (Repo, Commit, Run Link) to the file description. Default false. | | owner | Optional. Email of the user to impersonate (requires Domain-Wide Delegation). |
๐ค Output Parameters
The action provides the following outputs that can be used in subsequent steps:
Single File Upload:
file_id: The ID of the uploaded filefile_name: The name of the uploaded filewebviewlink: The web view link to access the file in Google Driveupload_count: The number of files uploaded (will be "1")
Multiple File Upload (using glob patterns):
file_ids: Comma-separated list of file IDsfile_names: Comma-separated list of file nameswebviewlinks: Comma-separated list of web view linksupload_count: The number of files uploaded
Example usage of outputs:
- name: Upload to Google Drive
id: upload
uses: Jumbo810/UploadGithubArtifactsTOGDrive@v2.3.5
with:
credentials: ${{ secrets.GOOGLE_CREDENTIALS }}
parentfolderid: ${{ secrets.GOOGLEPARENTFOLDER_ID }}
target: "./build/my-app.zip"
- name: Use the upload outputs
run: |
echo "File ID: ${{ steps.upload.outputs.file_id }}"
echo "File Name: ${{ steps.upload.outputs.file_name }}"
echo "Web View Link: ${{ steps.upload.outputs.webviewlink }}"
๐ Troubleshooting
Common Issues
- Authentication Errors
- File Not Found
- Permission Denied
- Multiple Files with Same Name
๐ Release Process
This project uses automated workflows to simplify the release process:
- Automatic Dist Updates: After successful CI runs on the master branch, the
dist/index.jsfile is automatically updated.
- Creating a Release:
package.json and CHANGELOG.md
- Commit with the message format: release: vX.Y.Z (e.g., git commit -m "release: v2.3.3")
- Push to master
- The workflow will automatically:
- Update dist/
- Create and push the Git Tag
- Create the GitHub Release with changelog notes
๐ค Contributing & Support
We welcome contributions! Please see our Contributing Guidelines for details on how to get started.
๐ Support the Project
If this project helped you save time or money, consider supporting its development via PayPal:
- PayPal: Donate via PayPal
- Need Help? Check out our Support Guide.
- Behavior: Please adhere to our Code of Conduct.
๐ Security
For security best practices when using this action, please refer to our Security Policy.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.