Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add library files #1

Merged
merged 7 commits into from
Jun 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
ci-info.cabal
dist
dist-*
cabal-dev
Expand Down
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
# ci-info-hs
Get details about the current Continuous Integration environment - Haskell port of https://github.com/watson/ci-info

Checks if the current environment is a Continuous Integration server.

This is a Haskell port of [watson/ci-info](https://github.com/watson/ci-info).

## Usage

Check if the current environment is a CI server:

```haskell
isCI :: IO Bool
```

Get the name of the CI vendor. Returns `Nothing` if no CI could be detected. Returns `Just CI_UNKNOWN_VENDOR` if a CI was detected, but the vendor name could not be determined:

```haskell
getCI :: IO (Maybe CI)
```
3 changes: 3 additions & 0 deletions Setup.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Distribution.Simple

main = defaultMain
36 changes: 36 additions & 0 deletions package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: ci-info
version: 0.1.0.0
github: "hasura/ci-info-hs"
license: MIT
author: "Ajeet D'Souza"
maintainer: "[email protected]"
copyright: "2019 Hasura Inc."

extra-source-files:
- README.md

description: Please see the README on GitHub at <https://github.com/hasura/ci-info-hs#readme>

dependencies:
- base >= 4.7 && < 5
- aeson
- aeson-casing
- hashable
- template-haskell
- th-lift-instances
- text
- unordered-containers

ghc-options:
- -Wall
- -Wincomplete-uni-patterns
- -Wincomplete-record-updates
- -Wcompat
- -Widentities
- -Wredundant-constraints
- -Wmissing-export-lists
- -Wpartial-fields

library:
exposed-modules: CI
source-dirs: src
159 changes: 159 additions & 0 deletions res/vendors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
[
{
"name": "AppVeyor",
"constant": "APPVEYOR",
"env": "APPVEYOR",
"pr": "APPVEYOR_PULL_REQUEST_NUMBER"
},
{
"name": "Azure Pipelines",
"constant": "AZURE_PIPELINES",
"env": "SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",
"pr": "SYSTEM_PULLREQUEST_PULLREQUESTID"
},
{
"name": "Bamboo",
"constant": "BAMBOO",
"env": "bamboo_planKey"
},
{
"name": "Bitbucket Pipelines",
"constant": "BITBUCKET",
"env": "BITBUCKET_COMMIT",
"pr": "BITBUCKET_PR_ID"
},
{
"name": "Bitrise",
"constant": "BITRISE",
"env": "BITRISE_IO",
"pr": "BITRISE_PULL_REQUEST"
},
{
"name": "Buddy",
"constant": "BUDDY",
"env": "BUDDY_WORKSPACE_ID",
"pr": "BUDDY_EXECUTION_PULL_REQUEST_ID"
},
{
"name": "Buildkite",
"constant": "BUILDKITE",
"env": "BUILDKITE",
"pr": { "env": "BUILDKITE_PULL_REQUEST", "ne": "false" }
},
{
"name": "CircleCI",
"constant": "CIRCLE",
"env": "CIRCLECI",
"pr": "CIRCLE_PULL_REQUEST"
},
{
"name": "Cirrus CI",
"constant": "CIRRUS",
"env": "CIRRUS_CI",
"pr": "CIRRUS_PR"
},
{
"name": "AWS CodeBuild",
"constant": "CODEBUILD",
"env": "CODEBUILD_BUILD_ARN"
},
{
"name": "Codeship",
"constant": "CODESHIP",
"env": { "CI_NAME": "codeship" }
},
{
"name": "Drone",
"constant": "DRONE",
"env": "DRONE",
"pr": { "DRONE_BUILD_EVENT": "pull_request" }
},
{
"name": "dsari",
"constant": "DSARI",
"env": "DSARI"
},
{
"name": "GitLab CI",
"constant": "GITLAB",
"env": "GITLAB_CI"
},
{
"name": "GoCD",
"constant": "GOCD",
"env": "GO_PIPELINE_LABEL"
},
{
"name": "Hudson",
"constant": "HUDSON",
"env": "HUDSON_URL"
},
{
"name": "Jenkins",
"constant": "JENKINS",
"env": ["JENKINS_URL", "BUILD_ID"],
"pr": { "any": ["ghprbPullId", "CHANGE_ID"] }
},
{
"name": "Magnum CI",
"constant": "MAGNUM",
"env": "MAGNUM"
},
{
"name": "Netlify CI",
"constant": "NETLIFY",
"env": "NETLIFY_BUILD_BASE",
"pr": { "env": "PULL_REQUEST", "ne": "false" }
},
{
"name": "Nevercode",
"constant": "NEVERCODE",
"env": "NEVERCODE",
"pr": { "env": "NEVERCODE_PULL_REQUEST", "ne": "false" }
},
{
"name": "Sail CI",
"constant": "SAIL",
"env": "SAILCI",
"pr": "SAIL_PULL_REQUEST_NUMBER"
},
{
"name": "Semaphore",
"constant": "SEMAPHORE",
"env": "SEMAPHORE",
"pr": "PULL_REQUEST_NUMBER"
},
{
"name": "Shippable",
"constant": "SHIPPABLE",
"env": "SHIPPABLE",
"pr": { "IS_PULL_REQUEST": "true" }
},
{
"name": "Solano CI",
"constant": "SOLANO",
"env": "TDDIUM",
"pr": "TDDIUM_PR_ID"
},
{
"name": "Strider CD",
"constant": "STRIDER",
"env": "STRIDER"
},
{
"name": "TaskCluster",
"constant": "TASKCLUSTER",
"env": ["TASK_ID", "RUN_ID"]
},
{
"name": "TeamCity",
"constant": "TEAMCITY",
"env": "TEAMCITY_VERSION"
},
{
"name": "Travis CI",
"constant": "TRAVIS",
"env": "TRAVIS",
"pr": { "env": "TRAVIS_PULL_REQUEST", "ne": "false" }
}
]
59 changes: 59 additions & 0 deletions src/CI.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}

module CI
( Types.CI(..)
, isCI
, getCI
) where

import Control.Arrow ((***))
import Data.Bool (bool)
import Data.Foldable (find)
import Data.Maybe (isJust)
import System.Environment (getEnvironment)

import CI.TH (getVendors)

import qualified Data.HashMap.Strict as HashMap
import qualified Data.Text as T

import qualified CI.Types as Types


vendors :: [Types.Vendor]
vendors = $(getVendors)

getCI :: IO (Maybe Types.CI)
getCI = do
env <- mkEnvMap <$> getEnvironment
let maybeVendor = find (checkVendor env) vendors
return
$ case maybeVendor of
Nothing -> bool Nothing (Just Types.CI_UNKNOWN_VENDOR)
$ checkUnknownVendor env
Just vendor -> Just $ Types.vendorConstant vendor
where
checkVendor env vendor = case Types.vendorEnv vendor of
(Types.VendorEnvString text) -> HashMap.member text env
(Types.VendorEnvList list) -> all (`HashMap.member` env) list
(Types.VendorEnvObject hashMap) -> all
(\(k, v) -> HashMap.lookup k env == Just v)
$ HashMap.toList hashMap

-- check vendor neutral environment variables
checkUnknownVendor env = any (`HashMap.member` env) unknownVendorEnvVars

unknownVendorEnvVars = map
Types.EnvVarName
[ "CI" -- Travis CI, CircleCI, Cirrus CI, Gitlab CI, Appveyor, CodeShip, dsari
, "CONTINUOUS_INTEGRATION" -- Travis CI, Cirrus CI
, "BUILD_NUMBER" -- Jenkins, TeamCity
, "RUN_ID" -- TaskCluster, dsari
]

mkEnvMap = HashMap.fromList
. map (Types.EnvVarName . T.pack *** Types.EnvVarValue . T.pack)

isCI :: IO Bool
isCI = isJust <$> getCI
22 changes: 22 additions & 0 deletions src/CI/TH.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module CI.TH
( getVendors
) where

import qualified Data.Aeson as Aeson
import qualified Language.Haskell.TH as TH
import qualified Language.Haskell.TH.Syntax as TH

import qualified CI.Types as Types


getVendors :: TH.Q TH.Exp
getVendors = TH.runIO readVendors >>= TH.lift
where
vendorsPath = "res/vendors.json"

readVendors :: IO [Types.Vendor]
readVendors = do
vendors <- Aeson.eitherDecodeFileStrict' vendorsPath
case vendors of
Left e -> fail $ "parsing vendors.json failed: " <> e
Right v -> return v
Loading