diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8557d4e..9f3bdff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,26 +24,26 @@ jobs: ormolu: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: haskell-actions/run-ormolu@v12 + - uses: actions/checkout@v4 + - uses: haskell-actions/run-ormolu@v15 with: version: "0.5.0.1" hlint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - name: 'Set up HLint' - uses: haskell/actions/hlint-setup@v2 - with: - version: '3.5' + - name: "Set up HLint" + uses: haskell/actions/hlint-setup@v2 + with: + version: "3.5" - - name: 'Run HLint' - uses: haskell/actions/hlint-run@v2 - with: - path: '["src/", "test/", "examples"]' - fail-on: warning + - name: "Run HLint" + uses: haskell/actions/hlint-run@v2 + with: + path: '["src/", "test/", "examples"]' + fail-on: warning cabal: name: ${{ matrix.os }} / ghc-${{ matrix.ghc }} / cabal-${{ matrix.cabal }} @@ -52,96 +52,95 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] # Removed macos-latest due to cert issues. - cabal: ["3.6", "3.8", "latest"] + cabal: ["3.8", "latest"] ghc: + - "9.6" - "9.4" - "9.2" - "9.0" - "8.10" - - "8.8" - - "8.6" - exclude: - - os: windows-latest - ghc: "9.4" - cabal: "3.6" + # exclude: + # - os: windows-latest + # ghc: "9.4" + # cabal: "3.6" steps: - - uses: actions/checkout@v3 - if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master' - - - uses: haskell/actions/setup@v2 - id: setup-haskell-cabal - name: Setup Haskell - with: - ghc-version: ${{ matrix.ghc }} - cabal-version: ${{ matrix.cabal }} - - - name: Configure - run: | - cabal configure --enable-tests --enable-benchmarks --test-show-details=direct -fexamples -fdev -flive-test - - - name: Freeze - run: | - cabal freeze - - - uses: actions/cache@v3 - name: Cache ~/.cabal/packages, ~/.cabal/store and dist-newstyle - with: - path: | - ~/.cabal/packages - ~/.cabal/store - dist-newstyle - key: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('**/*.cabal', '**/cabal.project', '**/cabal.project.freeze') }} - restore-keys: ${{ runner.os }}-${{ matrix.ghc }}- - - - name: Install dependencies - run: | - cabal build --only-dependencies - - - name: Build - run: | - cabal build - - - name: Setup MinIO for testing (Linux) - if: matrix.os == 'ubuntu-latest' - run: | - mkdir -p /tmp/minio /tmp/minio-config/certs - cp test/cert/* /tmp/minio-config/certs/ - (cd /tmp/minio; wget -q https://dl.min.io/server/minio/release/linux-amd64/minio; chmod +x ./minio) - sudo cp /tmp/minio-config/certs/public.crt /usr/local/share/ca-certificates/ - sudo update-ca-certificates - - - name: Setup MinIO for testing (MacOS) - if: matrix.os == 'macos-latest' - run: | - mkdir -p /tmp/minio /tmp/minio-config/certs - cp test/cert/* /tmp/minio-config/certs/ - (cd /tmp/minio; wget -q https://dl.min.io/server/minio/release/darwin-amd64/minio; chmod +x ./minio) - sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/minio-config/certs/public.crt - - - name: Setup MinIO for testing (Windows) - if: matrix.os == 'windows-latest' - run: | - New-Item -ItemType Directory -Path "$env:temp/minio-config/certs/" - Copy-Item -Path test\cert\* -Destination "$env:temp/minio-config/certs/" - Invoke-WebRequest -Uri https://dl.minio.io/server/minio/release/windows-amd64/minio.exe -OutFile $HOME/minio.exe - Import-Certificate -FilePath "$env:temp/minio-config/certs/public.crt" -CertStoreLocation Cert:\LocalMachine\Root - - - name: Test (Non-Windows) - if: matrix.os != 'windows-latest' - run: | - /tmp/minio/minio server --quiet --certs-dir /tmp/minio-config/certs data1 data2 data3 data4 2>&1 > minio.log & - ghc --version - cabal --version - cabal test - - - name: Test (Windows) - if: matrix.os == 'windows-latest' - run: | - Start-Process -NoNewWindow -FilePath "$HOME/minio.exe" -ArgumentList "--certs-dir", "$env:temp/minio-config/certs", "server", "$env:temp/data1", "$env:temp/data2", "$env:temp/data3", "$env:temp/data4" - ghc --version - cabal --version - cabal test + - uses: actions/checkout@v4 + if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master' + + - uses: haskell/actions/setup@v2 + id: setup-haskell-cabal + name: Setup Haskell + with: + ghc-version: ${{ matrix.ghc }} + cabal-version: ${{ matrix.cabal }} + + - name: Configure + run: | + cabal configure --enable-tests --enable-benchmarks --test-show-details=direct -fexamples -fdev -flive-test + + - name: Freeze + run: | + cabal freeze + + - uses: actions/cache@v3 + name: Cache ~/.cabal/packages, ~/.cabal/store and dist-newstyle + with: + path: | + ~/.cabal/packages + ~/.cabal/store + dist-newstyle + key: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('**/*.cabal', '**/cabal.project', '**/cabal.project.freeze') }} + restore-keys: ${{ runner.os }}-${{ matrix.ghc }}- + + - name: Install dependencies + run: | + cabal build --only-dependencies + + - name: Build + run: | + cabal build + + - name: Setup MinIO for testing (Linux) + if: matrix.os == 'ubuntu-latest' + run: | + mkdir -p /tmp/minio /tmp/minio-config/certs + cp test/cert/* /tmp/minio-config/certs/ + (cd /tmp/minio; wget -q https://dl.min.io/server/minio/release/linux-amd64/minio; chmod +x ./minio) + sudo cp /tmp/minio-config/certs/public.crt /usr/local/share/ca-certificates/ + sudo update-ca-certificates + + - name: Setup MinIO for testing (MacOS) + if: matrix.os == 'macos-latest' + run: | + mkdir -p /tmp/minio /tmp/minio-config/certs + cp test/cert/* /tmp/minio-config/certs/ + (cd /tmp/minio; wget -q https://dl.min.io/server/minio/release/darwin-amd64/minio; chmod +x ./minio) + sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/minio-config/certs/public.crt + + - name: Setup MinIO for testing (Windows) + if: matrix.os == 'windows-latest' + run: | + New-Item -ItemType Directory -Path "$env:temp/minio-config/certs/" + Copy-Item -Path test\cert\* -Destination "$env:temp/minio-config/certs/" + Invoke-WebRequest -Uri https://dl.minio.io/server/minio/release/windows-amd64/minio.exe -OutFile $HOME/minio.exe + Import-Certificate -FilePath "$env:temp/minio-config/certs/public.crt" -CertStoreLocation Cert:\LocalMachine\Root + + - name: Test (Non-Windows) + if: matrix.os != 'windows-latest' + run: | + /tmp/minio/minio server --quiet --certs-dir /tmp/minio-config/certs data1 data2 data3 data4 2>&1 > minio.log & + ghc --version + cabal --version + cabal test + + - name: Test (Windows) + if: matrix.os == 'windows-latest' + run: | + Start-Process -NoNewWindow -FilePath "$HOME/minio.exe" -ArgumentList "--certs-dir", "$env:temp/minio-config/certs", "server", "$env:temp/data1", "$env:temp/data2", "$env:temp/data3", "$env:temp/data4" + ghc --version + cabal --version + cabal test stack: name: stack / ghc ${{ matrix.ghc }} @@ -151,80 +150,83 @@ jobs: ghc: - "8.10.7" - "9.0.2" - - "9.2.4" + - "9.2.8" + - "9.4.8" + - "9.6.5" os: [ubuntu-latest] steps: - - uses: actions/checkout@v3 - if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master' - - - uses: haskell/actions/setup@v2 - name: Setup Haskell Stack - with: - enable-stack: true - ghc-version: ${{ matrix.ghc }} - stack-version: 'latest' - - - uses: actions/cache@v3 - name: Cache ~/.stack - with: - path: ~/.stack - key: ${{ runner.os }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }} - restore-keys: | - ${{ runner.os }}-stack-global- - - uses: actions/cache@v3 - name: Cache .stack-work - with: - path: .stack-work - key: ${{ runner.os }}-stack-work-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}-${{ hashFiles('**/*.hs') }} - restore-keys: | - ${{ runner.os }}-stack-work- - - - name: Install dependencies - run: | - stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks --only-dependencies - - - name: Build - run: | - stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks --flag minio-hs:examples --flag minio-hs:live-test --flag minio-hs:dev - - - name: Setup MinIO for testing (Linux) - if: matrix.os == 'ubuntu-latest' - run: | - mkdir -p /tmp/minio /tmp/minio-config/certs - cp test/cert/* /tmp/minio-config/certs/ - (cd /tmp/minio; wget -q https://dl.min.io/server/minio/release/linux-amd64/minio; chmod +x ./minio) - sudo cp /tmp/minio-config/certs/public.crt /usr/local/share/ca-certificates/ - sudo update-ca-certificates - - - name: Setup MinIO for testing (MacOS) - if: matrix.os == 'macos-latest' - run: | - mkdir -p /tmp/minio /tmp/minio-config/certs - cp test/cert/* /tmp/minio-config/certs/ - (cd /tmp/minio; wget -q https://dl.min.io/server/minio/release/darwin-amd64/minio; chmod +x ./minio) - sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/minio-config/certs/public.crt - - - name: Setup MinIO for testing (Windows) - if: matrix.os == 'windows-latest' - run: | - New-Item -ItemType Directory -Path "$env:temp/minio-config/certs/" - Copy-Item -Path test\cert\* -Destination "$env:temp/minio-config/certs/" - Invoke-WebRequest -Uri https://dl.minio.io/server/minio/release/windows-amd64/minio.exe -OutFile $HOME/minio.exe - Import-Certificate -FilePath "$env:temp/minio-config/certs/public.crt" -CertStoreLocation Cert:\LocalMachine\Root - - - name: Test (Non-Windows) - if: matrix.os != 'windows-latest' - run: | - /tmp/minio/minio server --quiet --certs-dir /tmp/minio-config/certs data1 data2 data3 data4 2>&1 > minio.log & - ghc --version - stack --version - stack test --system-ghc --flag minio-hs:live-test --flag minio-hs:dev - - - name: Test (Windows) - if: matrix.os == 'windows-latest' - run: | - Start-Process -NoNewWindow -FilePath "$HOME/minio.exe" -ArgumentList "--certs-dir", "$env:temp/minio-config/certs", "server", "$env:temp/data1", "$env:temp/data2", "$env:temp/data3", "$env:temp/data4" - ghc --version - cabal --version - stack test --system-ghc --flag minio-hs:live-test --flag minio-hs:dev + - uses: actions/checkout@v4 + if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master' + + - name: Install Haskell Stack + run: | + if ! which stack + then + curl -sSL https://get.haskellstack.org/ | sh + fi + + - uses: actions/cache@v3 + name: Cache ~/.stack + with: + path: ~/.stack + key: ${{ runner.os }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }} + restore-keys: | + ${{ runner.os }}-stack-global- + - uses: actions/cache@v3 + name: Cache .stack-work + with: + path: .stack-work + key: ${{ runner.os }}-stack-work-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}-${{ hashFiles('**/*.hs') }} + restore-keys: | + ${{ runner.os }}-stack-work- + + - name: Install dependencies + run: | + stack --version + stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks --only-dependencies + + - name: Build + run: | + stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks --flag minio-hs:examples --flag minio-hs:live-test --flag minio-hs:dev + + - name: Setup MinIO for testing (Linux) + if: matrix.os == 'ubuntu-latest' + run: | + mkdir -p /tmp/minio /tmp/minio-config/certs + cp test/cert/* /tmp/minio-config/certs/ + (cd /tmp/minio; wget -q https://dl.min.io/server/minio/release/linux-amd64/minio; chmod +x ./minio) + sudo cp /tmp/minio-config/certs/public.crt /usr/local/share/ca-certificates/ + sudo update-ca-certificates + + - name: Setup MinIO for testing (MacOS) + if: matrix.os == 'macos-latest' + run: | + mkdir -p /tmp/minio /tmp/minio-config/certs + cp test/cert/* /tmp/minio-config/certs/ + (cd /tmp/minio; wget -q https://dl.min.io/server/minio/release/darwin-amd64/minio; chmod +x ./minio) + sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/minio-config/certs/public.crt + + - name: Setup MinIO for testing (Windows) + if: matrix.os == 'windows-latest' + run: | + New-Item -ItemType Directory -Path "$env:temp/minio-config/certs/" + Copy-Item -Path test\cert\* -Destination "$env:temp/minio-config/certs/" + Invoke-WebRequest -Uri https://dl.minio.io/server/minio/release/windows-amd64/minio.exe -OutFile $HOME/minio.exe + Import-Certificate -FilePath "$env:temp/minio-config/certs/public.crt" -CertStoreLocation Cert:\LocalMachine\Root + + - name: Test (Non-Windows) + if: matrix.os != 'windows-latest' + run: | + /tmp/minio/minio server --quiet --certs-dir /tmp/minio-config/certs data1 data2 data3 data4 2>&1 > minio.log & + ghc --version + stack --version + stack test --system-ghc --flag minio-hs:live-test --flag minio-hs:dev + + - name: Test (Windows) + if: matrix.os == 'windows-latest' + run: | + Start-Process -NoNewWindow -FilePath "$HOME/minio.exe" -ArgumentList "--certs-dir", "$env:temp/minio-config/certs", "server", "$env:temp/data1", "$env:temp/data2", "$env:temp/data3", "$env:temp/data4" + ghc --version + cabal --version + stack test --system-ghc --flag minio-hs:live-test --flag minio-hs:dev diff --git a/minio-hs.cabal b/minio-hs.cabal index dab053d..3dd7fd0 100644 --- a/minio-hs.cabal +++ b/minio-hs.cabal @@ -22,12 +22,11 @@ extra-doc-files: extra-source-files: examples/*.hs stack.yaml -tested-with: GHC == 8.6.5 - , GHC == 8.8.4 - , GHC == 8.10.7 +tested-with: GHC == 8.10.7 , GHC == 9.0.2 - , GHC == 9.2.7 - , GHC == 9.4.5 + , GHC == 9.2.8 + , GHC == 9.4.8 + , GHC == 9.6.5 source-repository head type: git diff --git a/stack.yaml b/stack.yaml index f3a3b8a..e2a42cf 100644 --- a/stack.yaml +++ b/stack.yaml @@ -15,7 +15,7 @@ # resolver: # name: custom-snapshot # location: "./custom-snapshot.yaml" -resolver: lts-19.7 +resolver: lts-22.19 # User packages to be built. # Various formats can be used as shown in the example below. @@ -36,17 +36,17 @@ resolver: lts-19.7 # non-dependency (i.e. a user package), and its test suites and benchmarks # will not be run. This is useful for tweaking upstream packages. packages: -- '.' + - "." # Dependency packages to be pulled from upstream that are not in the resolver # (e.g., acme-missiles-0.3) -extra-deps: [] +extra-deps: + - crypton-connection-0.3.2 # Override default flag values for local packages and extra-deps flags: {} # Extra package databases containing global packages extra-package-dbs: [] - # Control whether we use the GHC we find on the path # system-ghc: true # diff --git a/stack.yaml.lock b/stack.yaml.lock index 8787e19..376760e 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -3,10 +3,17 @@ # For more information, please see the documentation at: # https://docs.haskellstack.org/en/stable/lock_files -packages: [] +packages: +- completed: + hackage: crypton-connection-0.3.2@sha256:c7937edc25ab022bcf167703f2ec5ab73b62908e545bb587d2aa42b33cd6f6cc,1581 + pantry-tree: + sha256: f986ad29b008cbe5732606e9cde1897191c486a2f1f169a4cb75fd915bce397c + size: 394 + original: + hackage: crypton-connection-0.3.2 snapshots: - completed: - size: 618884 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/7.yaml - sha256: 57d4ce67cc097fea2058446927987bc1f7408890e3a6df0da74e5e318f051c20 - original: lts-19.7 + sha256: e5cac927cf7ccbd52aa41476baa68b88c564ee6ddc3bc573dbf4210069287fe7 + size: 713340 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/19.yaml + original: lts-22.19 diff --git a/test/LiveServer.hs b/test/LiveServer.hs index b946da1..8a13f4f 100644 --- a/test/LiveServer.hs +++ b/test/LiveServer.hs @@ -49,6 +49,51 @@ main = defaultMain tests tests :: TestTree tests = testGroup "Tests" [liveServerUnitTests] +lookupTestEnv :: IO (Maybe ConnectInfo, (AccessKey, SecretKey)) +lookupTestEnv = do + val <- Env.lookupEnv "MINIO_LOCAL" + secure <- Env.lookupEnv "MINIO_SECURE" + let localServerMaybe = case (val, secure) of + (Just _, Just _) -> Just "https://localhost:9000" + (Just _, Nothing) -> Just "http://localhost:9000" + _ -> Nothing + accessKeyE <- Env.lookupEnv "MINIO_ACCESS_KEY" + let accessKey = maybe "minioadmin" fromString accessKeyE + secretKeyE <- Env.lookupEnv "MINIO_SECRET_KEY" + let secretKey = maybe "minioadmin" fromString secretKeyE + return (localServerMaybe, (accessKey, secretKey)) + +loadTestServerConnInfo :: IO ConnectInfo +loadTestServerConnInfo = do + (localServerMaybe, (ak, sk)) <- lookupTestEnv + return $ case localServerMaybe of + Just localServer -> do + setCreds (CredentialValue ak sk mempty) localServer + _ -> minioPlayCI + +loadTestServerConnInfoSTS :: IO ConnectInfo +loadTestServerConnInfoSTS = do + (localServerMaybe, (ak, sk)) <- lookupTestEnv + case localServerMaybe of + Just localServer -> do + let creds = CredentialValue ak sk mempty + assumeRole = + STSAssumeRole + { sarCredentials = creds, + sarOptions = defaultSTSAssumeRoleOptions + } + setSTSCredential assumeRole localServer + Nothing -> do + let creds = case connectCreds minioPlayCI of + CredsStatic c -> c + _ -> error "unexpected play creds" + assumeRole = + STSAssumeRole + { sarCredentials = creds, + sarOptions = defaultSTSAssumeRoleOptions + } + setSTSCredential assumeRole minioPlayCI + -- conduit that generates random binary stream of given length randomDataSrc :: (MonadIO m) => Int64 -> C.ConduitM () ByteString m () randomDataSrc = genBS @@ -76,34 +121,24 @@ mkRandFile size = do funTestBucketPrefix :: Text funTestBucketPrefix = "miniohstest-" -loadTestServerConnInfo :: IO ConnectInfo -loadTestServerConnInfo = do - val <- Env.lookupEnv "MINIO_LOCAL" - isSecure <- Env.lookupEnv "MINIO_SECURE" - return $ case (val, isSecure) of - (Just _, Just _) -> setCreds (CredentialValue "minio" "minio123" mempty) "https://localhost:9000" - (Just _, Nothing) -> setCreds (CredentialValue "minio" "minio123" mempty) "http://localhost:9000" - (Nothing, _) -> minioPlayCI - -loadTestServerConnInfoSTS :: IO ConnectInfo -loadTestServerConnInfoSTS = do - val <- Env.lookupEnv "MINIO_LOCAL" - isSecure <- Env.lookupEnv "MINIO_SECURE" - let cv = CredentialValue "minio" "minio123" mempty - assumeRole = - STSAssumeRole - { sarCredentials = cv, - sarOptions = defaultSTSAssumeRoleOptions - } - case (val, isSecure) of - (Just _, Just _) -> setSTSCredential assumeRole "https://localhost:9000" - (Just _, Nothing) -> setSTSCredential assumeRole "http://localhost:9000" - (Nothing, _) -> do - cv' <- case connectCreds minioPlayCI of - CredsStatic c -> return c - _ -> error "unexpected play creds" - let assumeRole' = assumeRole {sarCredentials = cv'} - setSTSCredential assumeRole' minioPlayCI +funTestWithBucketNoSTS :: + TestName -> + (([Char] -> Minio ()) -> Bucket -> Minio ()) -> + TestTree +funTestWithBucketNoSTS t minioTest = testCaseSteps t $ \step -> do + -- generate a random name for the bucket + bktSuffix <- liftIO $ generate $ Q.vectorOf 10 (Q.choose ('a', 'z')) + let b = T.concat [funTestBucketPrefix, T.pack bktSuffix] + liftStep = liftIO . step + connInfo <- loadTestServerConnInfo + ret <- runMinio connInfo $ do + liftStep $ "Creating bucket for test - " ++ t + foundBucket <- bucketExists b + liftIO $ foundBucket @?= False + makeBucket b Nothing + minioTest liftStep b + deleteBucket b + isRight ret @? ("Functional test " ++ t ++ " failed => " ++ show ret) funTestWithBucket :: TestName -> @@ -603,7 +638,7 @@ presignedUrlFunTest = funTestWithBucket "presigned Url tests" $ [] [] - print putUrl + -- print putUrl let size1 = 1000 :: Int64 inputFile <- mkRandFile size1 @@ -692,7 +727,7 @@ presignedUrlFunTest = funTestWithBucket "presigned Url tests" $ NC.httpLbs req mgr presignedPostPolicyFunTest :: TestTree -presignedPostPolicyFunTest = funTestWithBucket "Presigned Post Policy tests" $ +presignedPostPolicyFunTest = funTestWithBucketNoSTS "Presigned Post Policy tests" $ \step bucket -> do step "presignedPostPolicy basic test" now <- liftIO Time.getCurrentTime @@ -1222,9 +1257,10 @@ getNPutSSECTest = assumeRoleRequestTest :: TestTree assumeRoleRequestTest = testCaseSteps "Assume Role STS API" $ \step -> do step "Load credentials" + (_, (ak, sk)) <- lookupTestEnv val <- Env.lookupEnv "MINIO_LOCAL" isSecure <- Env.lookupEnv "MINIO_SECURE" - let localMinioCred = Just $ CredentialValue "minio" "minio123" mempty + let localMinioCred = Just $ CredentialValue ak sk mempty playCreds = case connectCreds minioPlayCI of CredsStatic c -> Just c