Skip to content

Commit

Permalink
prepare-workspace: make actions/checkout more reliable
Browse files Browse the repository at this point in the history
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
  • Loading branch information
NickVolynkin committed Nov 10, 2022
1 parent 1e1d91e commit bd6b200
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 1 deletion.
2 changes: 1 addition & 1 deletion cleanup/README.md
Original file line number Diff line number Diff line change
@@ -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).
Expand Down
57 changes: 57 additions & 0 deletions prepare-checkout/README.md
Original file line number Diff line number Diff line change
@@ -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.
13 changes: 13 additions & 0 deletions prepare-checkout/action.yml
Original file line number Diff line number Diff line change
@@ -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 [email protected] \
commit-tree $(git hash-object -t tree /dev/null) -m 'Empty commit' \
< /dev/null) || :
shell: bash

0 comments on commit bd6b200

Please sign in to comment.