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