From ba2fcf58cf73bf6922b07d2b95424c57901ec140 Mon Sep 17 00:00:00 2001 From: Nick Volynkin Date: Thu, 10 Nov 2022 16:26:30 +0600 Subject: [PATCH] prepare-workspace: make actions/checkout more reliable Make an empty detached commit for actions/checkout to properly clean the project's workspace before checking out new code revision. It makes the actions/checkout resilient to various problems related to git submodules. Part of #28 Related to tarantool/tarantool-qa#145 --- cleanup/README.md | 2 +- prepare-checkout/README.md | 57 +++++++++++++++++++++++++++++++++++++ prepare-checkout/action.yml | 13 +++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 prepare-checkout/README.md create mode 100644 prepare-checkout/action.yml diff --git a/cleanup/README.md b/cleanup/README.md index bab5c45..fc2f904 100644 --- a/cleanup/README.md +++ b/cleanup/README.md @@ -1,4 +1,4 @@ -# Setup environment +# Clean up the workspace 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). diff --git a/prepare-checkout/README.md b/prepare-checkout/README.md new file mode 100644 index 0000000..705f74b --- /dev/null +++ b/prepare-checkout/README.md @@ -0,0 +1,57 @@ +# Prepare workspace for checkout action + +This action creates and checks out an empty detached commit. +It helps subsequent [`actions/checkout`](https://github.com/actions/checkout) action +correctly clean the workspace. + +## Usage + +Add the following line to your workflow before the `actions/checkout` action: + +```diff ++ - uses: tarantool/actions/prepare-checkout@master + - uses: actions/checkout@v3 + ... +``` + +## Explanation and rationale + +This action is a solution for +[tarantool/tarantool-qa#145](https://github.com/tarantool/tarantool-qa/issues/145). +First attempt to solve this was the `tarantool/actions/cleanup` action. +The `tarantool/actions/prepare-checkout` action is a softer alternative to it. + +When submodules change, `actions/checkout` can fail 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 does not 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/prepare-checkout/action.yml b/prepare-checkout/action.yml new file mode 100644 index 0000000..67e7426 --- /dev/null +++ b/prepare-checkout/action.yml @@ -0,0 +1,13 @@ +--- +name: 'Prepare workspace for checkout' +description: 'Prepare workspace for the actions/checkout action' +runs: + using: 'composite' + steps: + - run: | + set -e + git checkout -f \ + $(git -c user.name=TarantoolBot -c user.email=bot@tarantool.io \ + commit-tree $(git hash-object -t tree /dev/null) -m 'Empty commit' \ + < /dev/null) || : + shell: bash