Caching is broken after directory changes

caching
bug

#1

The bash implementation of the caching layer has several bugs and I unfortunately hit another one. Once the directory is changed (for example in the script block), the wrong directory is considered for caching.

Reproducer

os: windows
language: shell
cache:
  directories
    - mydir
script:
- ls -la mydir
- echo stuff > mydir/stuff.txt
- mkdir build && cd build

Expected results

On the first run, mydir is empty and the entry should be saved. Expecting the message changes detected, packing new archive.
On the second run, mydir should not be empty.

Actual results

On the first run, mydir is empty and the entry is not saved. The following is shown:

Running casher in bash
nothing changed

Done. Your build exited with 0.

C:\Users\travis\build\Lekensteyn\...\build\mydir: No such file or directory
C:\Users\travis\build\Lekensteyn\...\build\mydir: unknown file type

Yes. stderr is confusingly written out-of-order and the wrong directory is considered (build\mydir instead of mydir).

Other information

https://docs.travis-ci.com/user/caching/ says:

As you can see, you can use environment variables as part of the directory path. After possible variable expansion, paths that

  • do not start with a / are relative to $TRAVIS_BUILD_DIR .
  • start with a / are absolute.

The first expectation (relative path support) is violated as shown above.
The second feature (absolute path support) is also broken. It is fixed by this PR from early January 2019: https://github.com/travis-ci/casher/pull/38 but it has unfortunately not received any feedback yet.

My guess is that the error message comes from https://github.com/travis-ci/casher/blob/4b355192a15f33e05eba438755a2ecb3ead36d10/bin/casher#L188

“PATHS_FILE” contains relative paths and thus tar -Pcjf ${PUSH_TAR} $(<${PATHS_FILE}) will fail.

Workaround

As a workaround for this issue, I will try to change the directory back to the original location in the script block, and change it back after the cache step. From ~/build.sh:

travis_run_install
travis_run_before_script
travis_run_script
travis_run_before_cache
travis_run_cache
travis_run_after_success
travis_run_after_failure
travis_run_after_script
travis_run_finish