From 0f14e8d5fd6fe734b28478ae1322b4d4067e8ed9 Mon Sep 17 00:00:00 2001 From: Nick Volynkin Date: Thu, 10 Nov 2022 16:26:30 +0600 Subject: [PATCH] cleanup: make an empty commit for actions/checkout Make an empty detached commit for actions/checkout to properly clean the project's workspace before checking out new code revision. Part of #28 Related to tarantool/tarantool-qa#145 --- cleanup/README.md | 54 +++++++++++++++++++++++++++++++++++++++------- cleanup/action.yml | 7 ++++-- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/cleanup/README.md b/cleanup/README.md index bab5c45..574b3a7 100644 --- a/cleanup/README.md +++ b/cleanup/README.md @@ -1,14 +1,52 @@ # Setup environment -Action cleans workspace directory after previous run. The main reason to add -this action is [tarantool/tarantool-qa#145](https://github.com/tarantool/tarantool-qa/issues/145). -When submodules are changed, the standard checkout fails with git errors. -It's a well-known problem and the related issue -[actions/checkout#418](https://github.com/actions/checkout/issues/418) is still opened. +Action creates an empty detached commit, which helps subsequent +[actions/checkout](https://github.com/actions/checkout) action +correctly clean the workspace. -## How to use GitHub Action from GitHub workflow +## Usage -Add the following code to the running steps before `checkout` action: +Add the following line to your workflow before the `actions/checkout` action: +```diff ++ - uses: tarantool/actions/cleanup@master + - uses: actions/checkout@v3 + ... ``` - - uses: tarantool/actions/cleanup@master + +## Explanation and rationale + +The main reason to add +this action is [tarantool/tarantool-qa#145](https://github.com/tarantool/tarantool-qa/issues/145). +When submodules change, actions/checkout fails with git errors. +It's a well-known problem and the related issues are still open: +actions/checkout#354, +actions/checkout#385, +actions/checkout#418, and +actions/checkout#590. + +Before checking out a new revision, actions/checkout runs the following code: + +```bash +# removes ignored and non-versioned files +git clean -ffdx +# resets workspace to the commit, on which it was left +# after the last job run +git reset --hard ``` + +The problem is that when a workflow fails because of a particular commit, +the repository still stays on that commit. On the next job run, +actions/checkout will run the above code, restore that particular commit, +and fail to make a proper code checkout. + +By creating a detached empty commit, this actions forces actions/checkout +to clean up the project's workspace entirely, removing any files that could +break checkout. Meanwhile, the `.git` directory stays intact, so full checkout +isn't required and the workflow doesn't waste much time. + +If this is a first job run on a particular runner and there's no repository yet, +the command in this action will silently fail, thanks to `|| :`, +but the action itself will succeed. + +This action uses a solution proposed in a +[comment](https://github.com/actions/checkout/issues/590#issuecomment-970586842) at actions/checkout#590. diff --git a/cleanup/action.yml b/cleanup/action.yml index 7d0b4c3..4dfb31a 100644 --- a/cleanup/action.yml +++ b/cleanup/action.yml @@ -1,11 +1,14 @@ --- name: 'Clean workspace' -description: 'Clean workspace directory after previous workflow run' +description: 'Clean workspace directory by making an empty detached commit' runs: using: 'composite' steps: - run: | set -e shopt -s dotglob - rm -rf ${{ github.workspace }}/* + git checkout -f \ + $(git -c user.name=TarantoolBot -c user.email=bot@tarantool.io commit-tree \ + $(git hash-object -t tree /dev/null) \ + < /dev/null) || : shell: bash