summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent P. René de Cotret <LaurentRDC@users.noreply.github.com>2020-06-30 08:57:47 -0400
committerGitHub <noreply@github.com>2020-06-30 14:57:47 +0200
commit3afebc0c8e80d1493e1605863176e9bfdf89784a (patch)
tree069b12f8e30a5f69ac99d167dbec6ce1b8273276
parent8afbb62ed5e969d78d8664df205646504f52f278 (diff)
downloadhakyll-3afebc0c8e80d1493e1605863176e9bfdf89784a.tar.gz
Continuous integration on Windows and Linux
-rw-r--r--.github/workflows/main.yml53
-rw-r--r--hakyll.cabal2
-rw-r--r--lib/Hakyll/Core/Util/File.hs30
3 files changed, 74 insertions, 11 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 9253d60..4e2b7c3 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -1,20 +1,55 @@
+# This Github Actions workflow is modified from
+# https://kodimensional.dev/github-actions
name: 'CI'
-on: ['push']
+
+# Trigger the workflow on push or pull request, but only for the master branch
+on: [push, pull_request]
+
jobs:
build:
+
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
+
+ env:
+ ARGS: --no-terminal --fast
name: ${{ matrix.os }}
- runs-on: $${{ matrix.os }}
+ runs-on: ${{ matrix.os }}
steps:
- - uses: 'actions/checkout@v1'
- - uses: 'mstksg/setup-stack@v1'
- - uses: 'actions/cache@v1'
+ - uses: actions/checkout@v2
+ if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
+
+ # https://github.com/actions/setup-haskell
+ - uses: actions/setup-haskell@v1.1
+ name: Setup Haskell Stack
with:
- path: '~/.stack'
- key: "${{ runner.os }}-v3-stack-${{ hashFiles('stack.yaml.lock') }}"
- restore-keys: '${{ runner.os }}-v3-stack'
- - run: 'stack build --test'
+ stack-version: "latest"
+ enable-stack: true
+ stack-no-global: true
+
+ # https://github.com/actions/cache
+ - uses: actions/cache@v2
+ name: Cache ~/.stack
+ with:
+ path: ~/.stack
+ key: ${{ runner.os }}-${{ hashFiles('stack.yaml') }}
+
+ # There are strange problems with CI on Windows, where builds with GHC 8.8.*
+ # always fail. Therefore, we distinguish between builds on Ubuntu and Windows
+ # and use an older compiler on Windows.
+ # See here for bug reports:
+ # https://gitlab.haskell.org/ghc/ghc/issues/17599
+ # https://gitlab.haskell.org/ghc/ghc/issues/17926
+
+ - name: Test (Ubuntu)
+ run: |
+ stack test $ARGS --stack-yaml stack.yaml
+ if: ${{ runner.os == 'Linux' }}
+
+ - name: Test (Windows)
+ run: |
+ stack test $ARGS --stack-yaml stack.yaml --compiler ghc-8.6.5
+ if: ${{ runner.os == 'Windows' }}
diff --git a/hakyll.cabal b/hakyll.cabal
index 4be61bc..6607ebf 100644
--- a/hakyll.cabal
+++ b/hakyll.cabal
@@ -173,7 +173,7 @@ Library
cryptonite >= 0.25 && < 0.27,
data-default >= 0.4 && < 0.8,
deepseq >= 1.3 && < 1.5,
- directory >= 1.0 && < 1.4,
+ directory >= 1.2.7.0 && < 1.4,
file-embed >= 0.0.10.1 && < 0.0.12,
filepath >= 1.0 && < 1.5,
lrucache >= 1.1.1 && < 1.3,
diff --git a/lib/Hakyll/Core/Util/File.hs b/lib/Hakyll/Core/Util/File.hs
index 9db6b11..02b8ece 100644
--- a/lib/Hakyll/Core/Util/File.hs
+++ b/lib/Hakyll/Core/Util/File.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE CPP #-}
--------------------------------------------------------------------------------
-- | A module containing various file utility functions
module Hakyll.Core.Util.File
@@ -8,10 +10,12 @@ module Hakyll.Core.Util.File
--------------------------------------------------------------------------------
+import Control.Concurrent (threadDelay)
+import Control.Exception (SomeException, catch)
import Control.Monad (filterM, forM, when)
import System.Directory (createDirectoryIfMissing,
doesDirectoryExist, getDirectoryContents,
- removeDirectoryRecursive)
+ removeDirectoryRecursive, removePathForcibly)
import System.FilePath (takeDirectory, (</>))
@@ -51,6 +55,30 @@ getRecursiveContents ignore top = go ""
--------------------------------------------------------------------------------
removeDirectory :: FilePath -> IO ()
+#ifndef mingw32_HOST_OS
removeDirectory fp = do
e <- doesDirectoryExist fp
when e $ removeDirectoryRecursive fp
+#else
+-- Deleting files on Windows is unreliable. If a file/directory is open by a program (e.g. antivirus),
+-- then removing related directories *quickly* may fail with strange messages.
+-- See here for discussions:
+-- https://github.com/haskell/directory/issues/96
+-- https://github.com/haskell/win32/pull/129
+--
+-- The hacky solution is to retry deleting directories a few times,
+-- with a delay, on Windows only.
+removeDirectory = retryWithDelay 10 . removePathForcibly
+#endif
+
+
+--------------------------------------------------------------------------------
+-- | Retry an operation at most /n/ times (/n/ must be positive).
+-- If the operation fails the /n/th time it will throw that final exception.
+-- A delay of 100ms is introduced between every retry.
+retryWithDelay :: Int -> IO a -> IO a
+retryWithDelay i x
+ | i <= 0 = error "Hakyll.Core.Util.File.retry: retry count must be 1 or more"
+ | i == 1 = x
+ | otherwise = catch x $ \(_::SomeException) -> threadDelay 100 >> retryWithDelay (i-1) x
+