Skip to content

Commit

Permalink
Add initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
antaljanosbenjamin committed Dec 28, 2020
1 parent d8f6c97 commit dbb8530
Show file tree
Hide file tree
Showing 10 changed files with 224 additions and 2 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: test
on: [push]
jobs:
test-example:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
branch: test-example-published-files
source-dir: test
files-and-dirs: 'a.txt b.txt some_dir "file with space.txt" "directory with space"'
test-simple:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
branch: test-simple-published-files
files-and-dirs: README.md
test-complex:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./
with:
github-token: ${{ secrets.PAT }}
github-actor: antaljanosbenjamin
github-repository: antaljanosbenjamin/test-repository
branch: test-complex-published-files
source-dir: test
files-and-dirs: 'a.txt ${{ github.workspace }}/test/b.txt some_dir other_dir/e.txt "file with space.txt" "directory with space"'
author-name: 'Test Author'
author-email: [email protected]
commit-message: 'Some very long commit message that uses build number and hashmark #${{ github.run_number }}'
test-source-dir-with-space:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
branch: test-source-dir-with-space-published-files
source-dir: test/directory with space
files-and-dirs: d.txt
55 changes: 53 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,53 @@
# single-commit-pusblish
Publishes files to the specified branch in a single commit with force push to erase history
# Single commit publish
This action can be used to publish files to the specified branch of a Github repository in a single commit with *force push to erase history*.

## Inputs

In general the `source-dir`, `files-and-dirs`, `author-name` and `commit-message` parameters can contain values with spaces, but for `files-and-dirs` such paths must be escaped by using double quotes. For the exact usage please check the [example](#example-usage).

### `github-token` (required)
GitHub token to use for push operation.

### `github-actor`
GitHub username to use for push operation. Defaults to `${{ github.actor }}`.
### `github-repository`
The GitHub repository to where the files should be published in `<username/repo>` format. Defaults to `${{ github.repository }}`.

### `branch` (required)
The branch to where the files should be published.

### `source-dir`
The source directory that contains all the files and directories that are going to be published. The directory structure inside this folder is going to be kept for the published files and directories. Defaults to `${{ github.workspace }}`.

### `files-and-dirs` (required)
List of paths (relative or absolute) of the files and directories to publish. They must be inside the source directory. The directory structure relative to source directory is kept for publishing.

### `author-name`
The name that will appear in the commit. Defaults to `github-actions`.

### `author-email`
The email that will appear in the commit. Defaults to `[email protected]`.

### `commit-message`
The commit message that will appear in the commit. Defaults to `"Publish from #${{ github.run_number }}"`.

## Example usage
```
name: test
on: [push]
jobs:
test-example:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: 'cd test'
shell: bash
- uses: antaljanosbenjamin/single-commit-publish@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
branch: test-example-published-files
source-dir: test
files-and-dirs: 'a.txt b.txt some_dir "file with space.txt" "directory with space"'
```

For further examples check the [test workflow](.github/workflows/test.yml).
42 changes: 42 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: 'Single commit publish'
description: 'Publishes files to the specified branch in a single commit with force push to erase history.'
inputs:
github-token:
description: 'GitHub token to use for push operation.'
required: true
github-actor:
description: 'GitHub username to use for push operation.'
required: false
default: ${{ github.actor }}
github-repository:
description: 'The GitHub repository to where the files should be published in <username/repo> format.'
required: false
default: ${{ github.repository }}
branch:
description: 'The branch to where the files should be published.'
required: true
source-dir:
description: 'The source directory that contains all the files and directories that are going to be published. The directory structure inside this folder is going to be kept for the published files and directories.'
required: false
default: ${{ github.workspace }}
files-and-dirs:
description: 'List of paths (relative or absolute) of the files and directories to publish. They must be inside the source directory. The directory structure relative to source directory is kept for publishing.'
required: true
author-name:
description: 'The name that will appear in the commit.'
required: false
default: github-actions
author-email:
description: 'The email that will appear in the commit.'
required: false
default: [email protected]
commit-message:
description: 'The commit message that will appear in the commit.'
required: false
default: 'Publish from #${{ github.run_number }}'
runs:
using: composite
steps:
- run: 'python3 ${{ github.action_path }}/main.py --github-token ${{ inputs.github-token }} --github-actor ${{ inputs.github-actor }} --github-repository ${{ inputs.github-repository }} --branch ${{ inputs.branch }} --files-and-dirs ${{ inputs.files-and-dirs }} --author-name "${{ inputs.author-name }}" --author-email "${{ inputs.author-email }}" --commit-message "${{ inputs.commit-message }}"'
shell: bash
working-directory: ${{ inputs.source-dir }}
76 changes: 76 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/python3

import argparse
import tempfile
import subprocess
import shutil
import os


def call_git(args):
subprocess.run(['git'] + args, check=True)


def copy_files_and_dirs(files_and_dirs, dest_dir):
rel_files_and_dirs = []
for file in files_and_dirs:
rel_path = os.path.relpath(file)
rel_files_and_dirs.append(rel_path)
dest_path = os.path.join(dest_dir, rel_path)
print(dest_path)
if os.path.isdir(file):
shutil.copytree(file, dest_path)
else:
os.makedirs(os.path.dirname(dest_path), exist_ok=True)
shutil.copy2(file, dest_path)

return rel_files_and_dirs


def main():
parser = argparse.ArgumentParser(
description='Publishes files to the specified branch in a single commit with force push to erase history.')
parser.add_argument('--github-token', '-t', action='store',
required=True, type=str, help='GitHub token to use for push operation.')
parser.add_argument('--github-actor', '-a', action='store',
required=True, type=str, help='GitHub username to use for push operation.')
parser.add_argument('--github-repository', '-r', action='store',
required=True, type=str, help='The GitHub repository to where the files should be published in <username/repo> format.')
parser.add_argument('--branch', '-b', action='store', required=True, type=str,
help='The branch to where the files should be published.')
parser.add_argument('--files-and-dirs', '-f', action='store', required=True, type=str,
nargs='+', help='List of paths (relative or absolute) of the files and directories to publish. They must be inside the current working directory. The directory structure relative to current working directory is kept for publishing.')
parser.add_argument('--author-name', '-u', action='store', required=True,
type=str, help='The name that will appear in the commit.')
parser.add_argument('--author-email', '-n', action='store', required=True,
type=str, help='The email that will appear in the commit.')
parser.add_argument('--commit-message', '-c', action='store', required=True,
type=str, help='The commit message that will appear in the commit.')

args = parser.parse_args()

print('Publishing files ({}) to branch {}'.format(
';'.join(args.files_and_dirs), args.branch))

with tempfile.TemporaryDirectory() as temp_dir:
print('Working directory is {}'.format(temp_dir))

rel_files_and_dirs = copy_files_and_dirs(args.files_and_dirs, temp_dir)
os.chdir(temp_dir)

remote_repo = 'https://{}:{}@github.com/{}.git'.format(
args.github_actor, args.github_token, args.github_repository)

call_git(['init'])
call_git(['config', 'user.name', args.author_name])
call_git(['config', 'user.email', args.author_email])
call_git(['remote', 'add', 'origin', remote_repo])
call_git(['checkout', '-b', args.branch])
call_git(['add', '-f'] + rel_files_and_dirs)
call_git(['commit', '-m', args.commit_message])
call_git(['push', 'origin', '{}:{}'.format(
args.branch, args.branch), '--force'])


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions test/a.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test a
1 change: 1 addition & 0 deletions test/b.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test b
1 change: 1 addition & 0 deletions test/directory with space/d.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test directory with space/d.txt
1 change: 1 addition & 0 deletions test/file with space.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test file with space.txt
1 change: 1 addition & 0 deletions test/other_dir/e.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test other_dir/e
1 change: 1 addition & 0 deletions test/some_dir/c.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test some_dir/c

0 comments on commit dbb8530

Please sign in to comment.