Skip to content

Commit

Permalink
feat(#478): ✨ possible to execute single steps (#516)
Browse files Browse the repository at this point in the history
* feat(#478): ✨ add option to split action

---------

Signed-off-by: Andy Augustin <dev@andreas-augustin.org>
  • Loading branch information
AndreasAugustin committed Apr 23, 2024
1 parent 67f86dd commit 6b9bd88
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 15 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
with:
source_repo_path: AndreasAugustin/template.git
is_dry_run: true
is_force_push_pr: true
- name: print output
env:
FORMER_OUTPUT_PR_BRANCH: ${{ steps.test.outputs.pr_branch }}
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/test_all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@ jobs:
permissions:
contents: write
pull-requests: write
call_test_steps:
uses: ./.github/workflows/test_steps.yml
secrets: inherit
permissions:
contents: write
pull-requests: write
47 changes: 47 additions & 0 deletions .github/workflows/test_steps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: test-steps

on:
push:
# branches:
# - "!main"
# pull_request:
workflow_call:
workflow_dispatch:

jobs:
test-implementation-job:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
# To use this repository's private action, you must check out the repository
- name: Checkout
uses: actions/checkout@v4

- name: Test action step first steps
uses: ./ # Uses an action in the root directory
with:
source_repo_path: AndreasAugustin/template.git
is_dry_run: true
is_force_push_pr: true
steps: "prechecks,pull"

- name: in between step
run: |
echo "I can do whatever I want"
git status
- name: Test action step next steps
uses: ./ # Uses an action in the root directory
id: test
with:
source_repo_path: AndreasAugustin/template.git
is_dry_run: true
is_force_push_pr: true
steps: "commit,push,pr"

- name: print output
env:
FORMER_OUTPUT_PR_BRANCH: ${{ steps.test.outputs.pr_branch }}
run: echo "pr_branch ${FORMER_OUTPUT_PR_BRANCH}"
74 changes: 74 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ jobs:
| git_remote_pull_params | `[optional]` set remote pull parameters | `false` | `--allow-unrelated-histories --squash --strategy=recursive -X theirs` |
| gpg_private_key | `[optional]` set if you want to sign commits | `false` | |
| gpg_passphrase | `[optional]` set if your optionial gpg private key has a passphrase | `false` | |
| steps | `[optional] add the steps you want to execute within the action` | `false` | all steps will be executed |

### Action Outputs

Expand Down Expand Up @@ -395,6 +396,79 @@ jobs:
```

## Lifecycle actions

The action has different phases which are executed in the following order

* **preparation** prepare and configure git related things
* init git
* auth related (ssh or github auth)
* [optional] gpg setup
* **prechecks** run some prechecks
* skipped if `is_force_push_pr` parameter is set to `true`
* check if the sync branch is already existing in target repository
* check if new changes of the source repository are already within history
* **pull** pull the changes from the remote repository into the action runtime
* **commit** commit the changes within the action runtime
* **push**
* if `is_force_push_pr` is set to true then a force push will be executed
* **pr**
* eventual create registered labels (:ninja: emojis are supported)
* create a new PR
* if `is_force_push_pr` is set to true then the PR will be created or edited
* [optional] **cleanup** eventual cleanup older PRs of the action
* set **github action outputs**

If `is_dry_run` parameter is set to true then all stages modifying the github state are not run (e.g. push, cleanup and pr).

It is possible to run a subset of the mentioned lifecycle actions.
**preparation** and **github action outputs** will be run every time.

:warning: Advanced feature. Use with care (possibly set `is_dry_run: true` configuration parameter for testing purposes)

e.g.

```yaml
# File: .github/workflows/test_steps.yml
on:
# cronjob trigger
schedule:
- cron: "0 0 1 * *"
# manual trigger
workflow_dispatch:
jobs:
repo-sync:
runs-on: ubuntu-latest
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
permissions:
contents: write
pull-requests: write
steps:
# To use this repository's private action, you must check out the repository
- name: Checkout
uses: actions/checkout@v4
- name: actions-template-sync first steps
uses: AndreasAugustin/actions-template-sync@v2
with:
source_repo_path: <owner/repo>
steps: "prechecks,pull" # order matters
- name: in between step
run: |
echo "I can do whatever I want"
git status
- name: actions-template-sync next steps
uses: AndreasAugustin/actions-template-sync@v2
with:
source_repo_path: <owner/repo>
steps: "commit,push,pr" # order matters
```

## Lifecycle hooks

Different lifecycle hooks are supported. You need to enable the functionality with the option `is_allow_hooks` and set it to `true`
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ inputs:
description: "[optional] set the gpg private key if you want to sign your commits"
gpg_passphrase:
description: "[optional] set if your private gpg key has a password"
steps:
description: "[optional] set the steps to execute within the action"
outputs:
pr_branch:
description: "The name of the PR branch"
Expand Down Expand Up @@ -108,3 +110,4 @@ runs:
GIT_REMOTE_PULL_PARAMS: ${{ inputs.git_remote_pull_params }}
GPG_PRIVATE_KEY: ${{ inputs.gpg_private_key }}
GPG_PASSPHRASE: ${{ inputs.gpg_passphrase }}
STEPS: ${{ inputs.steps }}
77 changes: 63 additions & 14 deletions src/sync_template.sh
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ function handle_templatesyncignore() {
# Logic
#######################################################

function prechecks() {
function arr_prechecks() {
info "prechecks"
echo "::group::prechecks"
if [ "${IS_FORCE_PUSH_PR}" == "true" ]; then
Expand All @@ -387,7 +387,7 @@ function prechecks() {
}


function checkout_branch_and_pull() {
function arr_checkout_branch_and_pull() {
info "checkout branch and pull"
cmd_from_yml "prepull"

Expand All @@ -409,7 +409,7 @@ function checkout_branch_and_pull() {
}


function commit() {
function arr_commit() {
info "commit"

cmd_from_yml "precommit"
Expand All @@ -428,8 +428,21 @@ function commit() {
}


function push_prepare_pr_create_pr() {
info "push_prepare_pr_create_pr"
function arr_push() {
info "push"

echo "::group::push"
if [ "$IS_DRY_RUN" == "true" ]; then
warn "dry_run option is set to on. skipping push"
return 0
fi
cmd_from_yml "prepush"
push "${PR_BRANCH}" "${IS_FORCE_PUSH_PR}"
echo "::endgroup::"
}

function arr_prepare_pr_create_pr() {
info "prepare_pr_create_pr"
if [ "$IS_DRY_RUN" == "true" ]; then
warn "dry_run option is set to on. skipping labels check, cleanup older PRs, push and create pr"
return 0
Expand All @@ -454,10 +467,8 @@ function push_prepare_pr_create_pr() {

echo "::endgroup::"

echo "::group::push changes and create PR"
echo "::group::create PR"

cmd_from_yml "prepush"
push "${PR_BRANCH}" "${IS_FORCE_PUSH_PR}"
cmd_from_yml "prepr"
if [ "$IS_FORCE_PUSH_PR" == true ] ; then
create_or_edit_pr "${PR_TITLE}" "${PR_BODY}" "${UPSTREAM_BRANCH}" "${PR_LABELS}" "${PR_REVIEWERS}"
Expand All @@ -469,13 +480,51 @@ function push_prepare_pr_create_pr() {
echo "::endgroup::"
}

declare -A cmd_arr
declare -a orders;

prechecks
cmd_arr["prechecks"]=arr_prechecks; orders+=("prechecks")
cmd_arr["pull"]=arr_checkout_branch_and_pull; orders+=("pull")
cmd_arr["commit"]=arr_commit; orders+=("commit")
cmd_arr["push"]=arr_push; orders+=("push")
cmd_arr["pr"]=arr_prepare_pr_create_pr; orders+=("pr")

checkout_branch_and_pull

commit

push_prepare_pr_create_pr
if [[ -z "${STEPS}" ]]; then
info "no steps provided. Default is to execute all."
for key in "${orders[@]}";
do
debug "execute cmd ${key}"
${cmd_arr[${key}]}
done
else
info "steps provided."
readarray -t steps < <(awk -F',' '{ for( i=1; i<=NF; i++ ) print $i }' <<<"${STEPS}")
# check if steps are supported
not_supported_steps=""
for step in "${steps[@]}";
do
matched=false
for key in "${orders[@]}";
do
debug "execute cmd ${key}"
if [[ "${step}" == "${key}" ]]; then
matched=true;
fi
done
if [[ "$matched" == 'false' ]]; then
not_supported_steps="${not_supported_steps} $step"
fi
done
if [[ -z "${not_supported_steps}" ]]; then
for step in "${steps[@]}";
do
debug "execute cmd ${step}"
${cmd_arr[${step}]}
done
else
err "following steps are not supported ${not_supported_steps}"
exit 1
fi
fi

set_github_action_outputs "${PR_BRANCH}" "${TEMPLATE_GIT_HASH}"
1 change: 0 additions & 1 deletion templatesync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ hooks:
commands:
- echo "foo ${MY_VAR}"
- echo 'hi, we are within the prepull phase'

prepush:
commands:
- echo 'hi, we are within the prepush phase'
Expand Down

0 comments on commit 6b9bd88

Please sign in to comment.