Repository: codecov/uploader
Pull request #307 (2021-08-16 14:46:12)

Release
- #287 chore(deps): update typescript-eslint monorepo to v4.29.1
- #290 chore(deps): update google/cloud-sdk docker tag to v352
- #294 Delete settings.json
- #295 Add "dist/*" to `exclude`
- #293 chore(deps): update node.js to v14.17.5
- #291 Add new Apex file format to upload ignore list
- #296 Don't upload coverage reports more than once
- #300 chore: Use snake-case package
- #302 fix(deps): pin dependency snake-case to 3.0.4
- #304 chore(deps): update node.js to v16.6.2
- #306 Remove filename validation


Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 7933cdf..af2f86a 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -11,7 +11,7 @@ jobs:
   build-linux-and-osx:
     docker:
       # specify the version you desire here
-      - image: circleci/node:16.6.1
+      - image: circleci/node:16.6.2
 
       # Specify service dependencies here if necessary
       # CircleCI maintains a library of pre-built images
@@ -183,7 +183,7 @@ jobs:
   test-linux:
     docker:
       # specify the version you desire here
-      - image: circleci/node:16.6.1
+      - image: circleci/node:16.6.2
     steps:
       - checkout
       - attach_workspace:
@@ -210,7 +210,7 @@ jobs:
 
   test-linux-without-git:
     docker:
-      - image: circleci/node:16.6.1
+      - image: circleci/node:16.6.2
     steps:
       - checkout
       - attach_workspace:
@@ -339,7 +339,7 @@ jobs:
 
   review:
     docker:
-      - image: circleci/node:16.6.1
+      - image: circleci/node:16.6.2
     steps:
       - attach_workspace:
           at: .
@@ -370,7 +370,7 @@ jobs:
 
   deploy:
     docker:
-      - image: circleci/node:16.6.1
+      - image: circleci/node:16.6.2
     steps:
       - attach_workspace:
           at: .
@@ -403,7 +403,7 @@ jobs:
             - release_tag
   release:
     docker:
-      - image: google/cloud-sdk:351.0.0-slim
+      - image: google/cloud-sdk:352.0.0-slim
     steps:
       - attach_workspace:
           # Must be absolute path or relative path from working_directory
diff --git a/.nvmrc b/.nvmrc
index 0627d19..18711d2 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1,1 +1,1 @@
-14.17.4
+14.17.5
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index 23fd35f..0000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-    "editor.formatOnSave": true
-}
\ No newline at end of file
diff --git a/bin/codecov.ts b/bin/codecov.ts
index 08e8163..a1e8c0a 100755
--- a/bin/codecov.ts
+++ b/bin/codecov.ts
@@ -1,130 +1,32 @@
 #!/usr/bin/env node
 
 import { logError, main, verbose} from '../src'
+import { addArguments } from '../src/helpers/cli'
 
 var argv = require('yargs') // eslint-disable-line
-  .usage('Usage: $0 <command> [options]')
-  .options({
-    build: {
-      alias: 'b',
-      description: 'Specify the build number manually',
-    },
-    branch: {
-      alias: 'B',
-      description: 'Specify the branch manually',
-    },
-    env: {
-      alias: 'e',
-      description:
-        'Specify environment variables to be included with this build.\nAlso accepting environment variables: CODECOV_ENV=VAR,VAR2',
-    },
-    sha: {
-      alias: 'C',
-      description: 'Specify the commit SHA mannually',
-    },
-    file: {
-      alias: 'f',
-      description: 'Target file(s) to upload',
-    },
-    flags: {
-      alias: 'F',
-      default: '',
-      description: 'Flag the upload to group coverage metrics',
-    },
-    name: {
-      alias: 'n',
-      default: '',
-      description: 'Custom defined name of the upload. Visible in Codecov UI',
-    },
-    parent: {
-      alias: 'N',
-      description:
-        "The commit SHA of the parent for which you are uploading coverage. If not present, the parent will be determined using the API of your repository provider. When using the repository provider's API, the parent is determined via finding the closest ancestor to the commit.",
-    },
-    pr: {
-      alias: 'P',
-      description: 'Specify the pull request number mannually',
-    },
-    dir: {
-      alias: 's',
-      description:
-        'Directory to search for coverage reports.\nAlready searches project root and current working directory',
-    },
-    token: {
-      alias: 't',
-      default: '',
-      description: 'Codecov upload token',
-    },
-    tag: {
-      alias: 'T',
-      default: '',
-      description: 'Specify the git tag',
-    },
-    verbose: {
-      alias: 'v',
-      type: 'boolean',
-      description: 'Run with verbose logging',
-    },
-    rootDir: {
-      alias: 'R',
-      description: 'Specify the project root directory when not in a git repo',
-    },
-    nonZero: {
-      alias: 'Z',
-      type: 'boolean',
-      default: false,
-      description: 'Should errors exit with a non-zero (default: false)',
-    },
-    dryRun: {
-      alias: 'd',
-      type: 'boolean',
-      description: "Don't upload files to Codecov",
-    },
-    slug: {
-      alias: 'r',
-      description: 'Specify the slug manually (Enterprise use)',
-    },
-    url: {
-      alias: 'u',
-      type: 'string',
-      description: 'Change the upload host (Enterprise use)',
-      default: 'https://codecov.io',
-    },
-    clean: {
-      alias: 'c',
-      type: 'boolean',
-      default: false,
-      description: 'Move discovered coverage reports to the trash',
-    },
-    feature: {
-      alias: 'X',
-      type: 'string',
-      description: `Toggle functionalities
-        -X network       Disable uploading the file network`,
-    },
-    source: {
-      alias: 'Q',
-      type: 'string',
-      default: '',
-      description: `Used internally by Codecov, this argument helps track wrappers
-        of the uploader (e.g. GitHub Action, CircleCI Orb)`,
-    },
-  })
-  .version()
+
+
+argv.usage('Usage: $0 <command> [options]')
+  
+addArguments(argv)
+
+  argv.version()
   .help('help')
   .alias('help', 'h').argv
 
-const start = Date.now()
+  const realArgs = argv.argv
+
+  const start = Date.now()
 
-verbose(`Start of uploader: ${start}...`)
-main(argv)
+verbose(`Start of uploader: ${start}...`, Boolean(argv.verbose))
+main(realArgs)
   .then(() => {
     const end = Date.now()
     verbose(`End of uploader: ${end - start} milliseconds`, argv.verbose,
     )
   })
   .catch(error => {
-    logError(`Error!: ${error}`)
+    logError(error)
     const end = Date.now()
     verbose(`End of uploader: ${end - start} milliseconds`, argv.verbose)
     process.exit(argv.nonZero ? -1 : 0)
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index 05ffd59..c2ad313 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -13,6 +13,7 @@
         "glob": "7.1.7",
         "js-yaml": "4.1.0",
         "line-reader": "0.4.0",
+        "snake-case": "3.0.4",
         "superagent": "6.1.0",
         "typescript": "4.3.5",
         "validator": "13.6.0",
@@ -29,8 +30,9 @@
         "@types/node": "16.3.3",
         "@types/superagent": "4.1.12",
         "@types/validator": "13.6.3",
-        "@typescript-eslint/eslint-plugin": "4.29.0",
-        "@typescript-eslint/parser": "4.29.0",
+        "@types/yargs": "17.0.2",
+        "@typescript-eslint/eslint-plugin": "4.29.1",
+        "@typescript-eslint/parser": "4.29.1",
         "eslint": "7.32.0",
         "eslint-config-prettier": "8.3.0",
         "husky": "7.0.1",
@@ -1050,6 +1052,15 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/@jest/types/node_modules/@types/yargs": {
+      "version": "16.0.4",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+      "dev": true,
+      "dependencies": {
+        "@types/yargs-parser": "*"
+      }
+    },
     "node_modules/@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -1216,9 +1227,9 @@
       "dev": true
     },
     "node_modules/@types/json-schema": {
-      "version": "7.0.8",
-      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz",
-      "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==",
+      "version": "7.0.9",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
+      "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
       "dev": true
     },
     "node_modules/@types/minimatch": {
@@ -1277,9 +1288,9 @@
       "dev": true
     },
     "node_modules/@types/yargs": {
-      "version": "16.0.4",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+      "version": "17.0.2",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.2.tgz",
+      "integrity": "sha512-JhZ+pNdKMfB0rXauaDlrIvm+U7V4m03PPOSVoPS66z8gf+G4Z/UW8UlrVIj2MRQOBzuoEvYtjS0bqYwnpZaS9Q==",
       "dev": true,
       "dependencies": {
         "@types/yargs-parser": "*"
@@ -1292,13 +1303,13 @@
       "dev": true
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.0.tgz",
-      "integrity": "sha512-eiREtqWRZ8aVJcNru7cT/AMVnYd9a2UHsfZT8MR1dW3UUEg6jDv9EQ9Cq4CUPZesyQ58YUpoAADGv71jY8RwgA==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.1.tgz",
+      "integrity": "sha512-AHqIU+SqZZgBEiWOrtN94ldR3ZUABV5dUG94j8Nms9rQnHFc8fvDOue/58K4CFz6r8OtDDc35Pw9NQPWo0Ayrw==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/experimental-utils": "4.29.0",
-        "@typescript-eslint/scope-manager": "4.29.0",
+        "@typescript-eslint/experimental-utils": "4.29.1",
+        "@typescript-eslint/scope-manager": "4.29.1",
         "debug": "^4.3.1",
         "functional-red-black-tree": "^1.0.1",
         "regexpp": "^3.1.0",
@@ -1323,15 +1334,15 @@
       }
     },
     "node_modules/@typescript-eslint/experimental-utils": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.0.tgz",
-      "integrity": "sha512-FpNVKykfeaIxlArLUP/yQfv/5/3rhl1ov6RWgud4OgbqWLkEq7lqgQU9iiavZRzpzCRQV4XddyFz3wFXdkiX9w==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.1.tgz",
+      "integrity": "sha512-kl6QG6qpzZthfd2bzPNSJB2YcZpNOrP6r9jueXupcZHnL74WiuSjaft7WSu17J9+ae9zTlk0KJMXPUj0daBxMw==",
       "dev": true,
       "dependencies": {
         "@types/json-schema": "^7.0.7",
-        "@typescript-eslint/scope-manager": "4.29.0",
-        "@typescript-eslint/types": "4.29.0",
-        "@typescript-eslint/typescript-estree": "4.29.0",
+        "@typescript-eslint/scope-manager": "4.29.1",
+        "@typescript-eslint/types": "4.29.1",
+        "@typescript-eslint/typescript-estree": "4.29.1",
         "eslint-scope": "^5.1.1",
         "eslint-utils": "^3.0.0"
       },
@@ -1347,14 +1358,14 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.0.tgz",
-      "integrity": "sha512-+92YRNHFdXgq+GhWQPT2bmjX09X7EH36JfgN2/4wmhtwV/HPxozpCNst8jrWcngLtEVd/4zAwA6BKojAlf+YqA==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.1.tgz",
+      "integrity": "sha512-3fL5iN20hzX3Q4OkG7QEPFjZV2qsVGiDhEwwh+EkmE/w7oteiOvUNzmpu5eSwGJX/anCryONltJ3WDmAzAoCMg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "4.29.0",
-        "@typescript-eslint/types": "4.29.0",
-        "@typescript-eslint/typescript-estree": "4.29.0",
+        "@typescript-eslint/scope-manager": "4.29.1",
+        "@typescript-eslint/types": "4.29.1",
+        "@typescript-eslint/typescript-estree": "4.29.1",
         "debug": "^4.3.1"
       },
       "engines": {
@@ -1374,13 +1385,13 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.0.tgz",
-      "integrity": "sha512-HPq7XAaDMM3DpmuijxLV9Io8/6pQnliiXMQUcAdjpJJSR+fdmbD/zHCd7hMkjJn04UQtCQBtshgxClzg6NIS2w==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.1.tgz",
+      "integrity": "sha512-Hzv/uZOa9zrD/W5mftZa54Jd5Fed3tL6b4HeaOpwVSabJK8CJ+2MkDasnX/XK4rqP5ZTWngK1ZDeCi6EnxPQ7A==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "4.29.0",
-        "@typescript-eslint/visitor-keys": "4.29.0"
+        "@typescript-eslint/types": "4.29.1",
+        "@typescript-eslint/visitor-keys": "4.29.1"
       },
       "engines": {
         "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
@@ -1391,9 +1402,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.0.tgz",
-      "integrity": "sha512-2YJM6XfWfi8pgU2HRhTp7WgRw78TCRO3dOmSpAvIQ8MOv4B46JD2chnhpNT7Jq8j0APlIbzO1Bach734xxUl4A==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.1.tgz",
+      "integrity": "sha512-Jj2yu78IRfw4nlaLtKjVaGaxh/6FhofmQ/j8v3NXmAiKafbIqtAPnKYrf0sbGjKdj0hS316J8WhnGnErbJ4RCA==",
       "dev": true,
       "engines": {
         "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
@@ -1404,13 +1415,13 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.0.tgz",
-      "integrity": "sha512-8ZpNHDIOyqzzgZrQW9+xQ4k5hM62Xy2R4RPO3DQxMc5Rq5QkCdSpk/drka+DL9w6sXNzV5nrdlBmf8+x495QXQ==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.1.tgz",
+      "integrity": "sha512-lIkkrR9E4lwZkzPiRDNq0xdC3f2iVCUjw/7WPJ4S2Sl6C3nRWkeE1YXCQ0+KsiaQRbpY16jNaokdWnm9aUIsfw==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "4.29.0",
-        "@typescript-eslint/visitor-keys": "4.29.0",
+        "@typescript-eslint/types": "4.29.1",
+        "@typescript-eslint/visitor-keys": "4.29.1",
         "debug": "^4.3.1",
         "globby": "^11.0.3",
         "is-glob": "^4.0.1",
@@ -1431,12 +1442,12 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.0.tgz",
-      "integrity": "sha512-LoaofO1C/jAJYs0uEpYMXfHboGXzOJeV118X4OsZu9f7rG7Pr9B3+4HTU8+err81rADa4xfQmAxnRnPAI2jp+Q==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.1.tgz",
+      "integrity": "sha512-zLqtjMoXvgdZY/PG6gqA73V8BjqPs4af1v2kiiETBObp+uC6gRYnJLmJHxC0QyUrrHDLJPIWNYxoBV3wbcRlag==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "4.29.0",
+        "@typescript-eslint/types": "4.29.1",
         "eslint-visitor-keys": "^2.0.0"
       },
       "engines": {
@@ -2363,6 +2374,15 @@
         "node": ">=8"
       }
     },
+    "node_modules/dot-case": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+      "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+      "dependencies": {
+        "no-case": "^3.0.4",
+        "tslib": "^2.0.3"
+      }
+    },
     "node_modules/electron-to-chromium": {
       "version": "1.3.790",
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.790.tgz",
@@ -3033,9 +3053,7 @@
       "dev": true,
       "hasInstallScript": true,
       "optional": true,
-      "os": [
-        "darwin"
-      ],
+      "os": ["darwin"],
       "engines": {
         "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
       }
@@ -4423,6 +4441,15 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/jest-runtime/node_modules/@types/yargs": {
+      "version": "16.0.4",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+      "dev": true,
+      "dependencies": {
+        "@types/yargs-parser": "*"
+      }
+    },
     "node_modules/jest-serializer": {
       "version": "27.0.6",
       "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz",
@@ -4988,6 +5015,14 @@
         "node": ">=8"
       }
     },
+    "node_modules/lower-case": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+      "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+      "dependencies": {
+        "tslib": "^2.0.3"
+      }
+    },
     "node_modules/lru-cache": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -5228,6 +5263,15 @@
       "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
       "dev": true
     },
+    "node_modules/no-case": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+      "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+      "dependencies": {
+        "lower-case": "^2.0.2",
+        "tslib": "^2.0.3"
+      }
+    },
     "node_modules/nock": {
       "version": "13.1.1",
       "resolved": "https://registry.npmjs.org/nock/-/nock-13.1.1.tgz",
@@ -6202,6 +6246,15 @@
         "node": ">=8"
       }
     },
+    "node_modules/snake-case": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
+      "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
+      "dependencies": {
+        "dot-case": "^3.0.4",
+        "tslib": "^2.0.3"
+      }
+    },
     "node_modules/source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -6712,8 +6765,7 @@
     "node_modules/tslib": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
-      "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==",
-      "dev": true
+      "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
     },
     "node_modules/tsutils": {
       "version": "3.21.0",
@@ -7912,6 +7964,17 @@
         "@types/node": "*",
         "@types/yargs": "^16.0.0",
         "chalk": "^4.0.0"
+      },
+      "dependencies": {
+        "@types/yargs": {
+          "version": "16.0.4",
+          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+          "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+          "dev": true,
+          "requires": {
+            "@types/yargs-parser": "*"
+          }
+        }
       }
     },
     "@nodelib/fs.scandir": {
@@ -8068,9 +8131,9 @@
       "dev": true
     },
     "@types/json-schema": {
-      "version": "7.0.8",
-      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz",
-      "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==",
+      "version": "7.0.9",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
+      "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
       "dev": true
     },
     "@types/minimatch": {
@@ -8129,9 +8192,9 @@
       "dev": true
     },
     "@types/yargs": {
-      "version": "16.0.4",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+      "version": "17.0.2",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.2.tgz",
+      "integrity": "sha512-JhZ+pNdKMfB0rXauaDlrIvm+U7V4m03PPOSVoPS66z8gf+G4Z/UW8UlrVIj2MRQOBzuoEvYtjS0bqYwnpZaS9Q==",
       "dev": true,
       "requires": {
         "@types/yargs-parser": "*"
@@ -8144,13 +8207,13 @@
       "dev": true
     },
     "@typescript-eslint/eslint-plugin": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.0.tgz",
-      "integrity": "sha512-eiREtqWRZ8aVJcNru7cT/AMVnYd9a2UHsfZT8MR1dW3UUEg6jDv9EQ9Cq4CUPZesyQ58YUpoAADGv71jY8RwgA==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.1.tgz",
+      "integrity": "sha512-AHqIU+SqZZgBEiWOrtN94ldR3ZUABV5dUG94j8Nms9rQnHFc8fvDOue/58K4CFz6r8OtDDc35Pw9NQPWo0Ayrw==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/experimental-utils": "4.29.0",
-        "@typescript-eslint/scope-manager": "4.29.0",
+        "@typescript-eslint/experimental-utils": "4.29.1",
+        "@typescript-eslint/scope-manager": "4.29.1",
         "debug": "^4.3.1",
         "functional-red-black-tree": "^1.0.1",
         "regexpp": "^3.1.0",
@@ -8159,55 +8222,55 @@
       }
     },
     "@typescript-eslint/experimental-utils": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.0.tgz",
-      "integrity": "sha512-FpNVKykfeaIxlArLUP/yQfv/5/3rhl1ov6RWgud4OgbqWLkEq7lqgQU9iiavZRzpzCRQV4XddyFz3wFXdkiX9w==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.1.tgz",
+      "integrity": "sha512-kl6QG6qpzZthfd2bzPNSJB2YcZpNOrP6r9jueXupcZHnL74WiuSjaft7WSu17J9+ae9zTlk0KJMXPUj0daBxMw==",
       "dev": true,
       "requires": {
         "@types/json-schema": "^7.0.7",
-        "@typescript-eslint/scope-manager": "4.29.0",
-        "@typescript-eslint/types": "4.29.0",
-        "@typescript-eslint/typescript-estree": "4.29.0",
+        "@typescript-eslint/scope-manager": "4.29.1",
+        "@typescript-eslint/types": "4.29.1",
+        "@typescript-eslint/typescript-estree": "4.29.1",
         "eslint-scope": "^5.1.1",
         "eslint-utils": "^3.0.0"
       }
     },
     "@typescript-eslint/parser": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.0.tgz",
-      "integrity": "sha512-+92YRNHFdXgq+GhWQPT2bmjX09X7EH36JfgN2/4wmhtwV/HPxozpCNst8jrWcngLtEVd/4zAwA6BKojAlf+YqA==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.1.tgz",
+      "integrity": "sha512-3fL5iN20hzX3Q4OkG7QEPFjZV2qsVGiDhEwwh+EkmE/w7oteiOvUNzmpu5eSwGJX/anCryONltJ3WDmAzAoCMg==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/scope-manager": "4.29.0",
-        "@typescript-eslint/types": "4.29.0",
-        "@typescript-eslint/typescript-estree": "4.29.0",
+        "@typescript-eslint/scope-manager": "4.29.1",
+        "@typescript-eslint/types": "4.29.1",
+        "@typescript-eslint/typescript-estree": "4.29.1",
         "debug": "^4.3.1"
       }
     },
     "@typescript-eslint/scope-manager": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.0.tgz",
-      "integrity": "sha512-HPq7XAaDMM3DpmuijxLV9Io8/6pQnliiXMQUcAdjpJJSR+fdmbD/zHCd7hMkjJn04UQtCQBtshgxClzg6NIS2w==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.1.tgz",
+      "integrity": "sha512-Hzv/uZOa9zrD/W5mftZa54Jd5Fed3tL6b4HeaOpwVSabJK8CJ+2MkDasnX/XK4rqP5ZTWngK1ZDeCi6EnxPQ7A==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "4.29.0",
-        "@typescript-eslint/visitor-keys": "4.29.0"
+        "@typescript-eslint/types": "4.29.1",
+        "@typescript-eslint/visitor-keys": "4.29.1"
       }
     },
     "@typescript-eslint/types": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.0.tgz",
-      "integrity": "sha512-2YJM6XfWfi8pgU2HRhTp7WgRw78TCRO3dOmSpAvIQ8MOv4B46JD2chnhpNT7Jq8j0APlIbzO1Bach734xxUl4A==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.1.tgz",
+      "integrity": "sha512-Jj2yu78IRfw4nlaLtKjVaGaxh/6FhofmQ/j8v3NXmAiKafbIqtAPnKYrf0sbGjKdj0hS316J8WhnGnErbJ4RCA==",
       "dev": true
     },
     "@typescript-eslint/typescript-estree": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.0.tgz",
-      "integrity": "sha512-8ZpNHDIOyqzzgZrQW9+xQ4k5hM62Xy2R4RPO3DQxMc5Rq5QkCdSpk/drka+DL9w6sXNzV5nrdlBmf8+x495QXQ==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.1.tgz",
+      "integrity": "sha512-lIkkrR9E4lwZkzPiRDNq0xdC3f2iVCUjw/7WPJ4S2Sl6C3nRWkeE1YXCQ0+KsiaQRbpY16jNaokdWnm9aUIsfw==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "4.29.0",
-        "@typescript-eslint/visitor-keys": "4.29.0",
+        "@typescript-eslint/types": "4.29.1",
+        "@typescript-eslint/visitor-keys": "4.29.1",
         "debug": "^4.3.1",
         "globby": "^11.0.3",
         "is-glob": "^4.0.1",
@@ -8216,12 +8279,12 @@
       }
     },
     "@typescript-eslint/visitor-keys": {
-      "version": "4.29.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.0.tgz",
-      "integrity": "sha512-LoaofO1C/jAJYs0uEpYMXfHboGXzOJeV118X4OsZu9f7rG7Pr9B3+4HTU8+err81rADa4xfQmAxnRnPAI2jp+Q==",
+      "version": "4.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.1.tgz",
+      "integrity": "sha512-zLqtjMoXvgdZY/PG6gqA73V8BjqPs4af1v2kiiETBObp+uC6gRYnJLmJHxC0QyUrrHDLJPIWNYxoBV3wbcRlag==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "4.29.0",
+        "@typescript-eslint/types": "4.29.1",
         "eslint-visitor-keys": "^2.0.0"
       }
     },
@@ -8918,6 +8981,15 @@
         }
       }
     },
+    "dot-case": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+      "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+      "requires": {
+        "no-case": "^3.0.4",
+        "tslib": "^2.0.3"
+      }
+    },
     "electron-to-chromium": {
       "version": "1.3.790",
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.790.tgz",
@@ -10458,6 +10530,17 @@
         "slash": "^3.0.0",
         "strip-bom": "^4.0.0",
         "yargs": "^16.0.3"
+      },
+      "dependencies": {
+        "@types/yargs": {
+          "version": "16.0.4",
+          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+          "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+          "dev": true,
+          "requires": {
+            "@types/yargs-parser": "*"
+          }
+        }
       }
     },
     "jest-serializer": {
@@ -10902,6 +10985,14 @@
         }
       }
     },
+    "lower-case": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+      "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+      "requires": {
+        "tslib": "^2.0.3"
+      }
+    },
     "lru-cache": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -11075,6 +11166,15 @@
       "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
       "dev": true
     },
+    "no-case": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+      "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+      "requires": {
+        "lower-case": "^2.0.2",
+        "tslib": "^2.0.3"
+      }
+    },
     "nock": {
       "version": "13.1.1",
       "resolved": "https://registry.npmjs.org/nock/-/nock-13.1.1.tgz",
@@ -11793,6 +11893,15 @@
         "is-fullwidth-code-point": "^3.0.0"
       }
     },
+    "snake-case": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
+      "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
+      "requires": {
+        "dot-case": "^3.0.4",
+        "tslib": "^2.0.3"
+      }
+    },
     "source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -12192,8 +12301,7 @@
     "tslib": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
-      "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==",
-      "dev": true
+      "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
     },
     "tsutils": {
       "version": "3.21.0",
diff --git a/package.json b/package.json
index b5b267c..688a6cc 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,7 @@
     "glob": "7.1.7",
     "js-yaml": "4.1.0",
     "line-reader": "0.4.0",
+    "snake-case": "3.0.4",
     "superagent": "6.1.0",
     "typescript": "4.3.5",
     "validator": "13.6.0",
@@ -46,8 +47,9 @@
     "@types/node": "16.3.3",
     "@types/superagent": "4.1.12",
     "@types/validator": "13.6.3",
-    "@typescript-eslint/eslint-plugin": "4.29.0",
-    "@typescript-eslint/parser": "4.29.0",
+    "@types/yargs": "17.0.2",
+    "@typescript-eslint/eslint-plugin": "4.29.1",
+    "@typescript-eslint/parser": "4.29.1",
     "eslint": "7.32.0",
     "eslint-config-prettier": "8.3.0",
     "husky": "7.0.1",
diff --git a/src/ci_providers/provider_appveyorci.ts b/src/ci_providers/provider_appveyorci.ts
index 94aea51..48d4454 100644
--- a/src/ci_providers/provider_appveyorci.ts
+++ b/src/ci_providers/provider_appveyorci.ts
@@ -8,12 +8,12 @@ export function detect(envs: UploaderEnvs): boolean {
 }
 
 function _getBuild(inputs: UploaderInputs) {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || encodeURIComponent(envs.APPVEYOR_JOB_ID || '')
 }
 
 function _getBuildURL(inputs: UploaderInputs) {
-  const { envs } = inputs
+  const { environment: envs } = inputs
   if (
     envs.APPVEYOR_URL &&
     envs.APPVEYOR_REPO_NAME &&
@@ -28,7 +28,7 @@ function _getBuildURL(inputs: UploaderInputs) {
 }
 
 function _getBranch(inputs: UploaderInputs) {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.branch || envs.APPVEYOR_REPO_BRANCH || ''
 }
 
@@ -44,7 +44,7 @@ function _getJob(envs: UploaderEnvs) {
 }
 
 function _getPR(inputs: UploaderInputs): number {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return Number(args.pr || envs.APPVEYOR_PULL_REQUEST_NUMBER || '')
 }
 
@@ -57,12 +57,12 @@ export function getServiceName() {
 }
 
 function _getSHA(inputs: UploaderInputs) {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.sha || envs.APPVEYOR_REPO_COMMIT || ''
 }
 
 function _getSlug(inputs: UploaderInputs) {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.slug || envs.APPVEYOR_REPO_NAME || ''
 }
 
@@ -72,7 +72,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_azurepipelines.ts b/src/ci_providers/provider_azurepipelines.ts
index 30b54b9..c25c719 100644
--- a/src/ci_providers/provider_azurepipelines.ts
+++ b/src/ci_providers/provider_azurepipelines.ts
@@ -7,12 +7,12 @@ export function detect(envs: UploaderEnvs): boolean {
 }
 
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.BUILD_BUILDNUMBER || ''
 }
 
 function _getBuildURL(inputs: UploaderInputs): string {
-  const { envs } = inputs
+  const { environment: envs } = inputs
   if (envs.SYSTEM_TEAMPROJECT && envs.BUILD_BUILDID) {
     return encodeURIComponent(
       `${envs.SYSTEM_TEAMFOUNDATIONSERVERURI}${envs.SYSTEM_TEAMPROJECT}/_build/results?buildId=${envs.BUILD_BUILDID}`,
@@ -22,7 +22,7 @@ function _getBuildURL(inputs: UploaderInputs): string {
 }
 
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   let branch = ''
   if (envs.BUILD_SOURCEBRANCH) {
     branch = envs.BUILD_SOURCEBRANCH.toString().replace('refs/heads/', '')
@@ -35,7 +35,7 @@ function _getJob(envs: UploaderEnvs): string {
 }
 
 function _getPR(inputs: UploaderInputs): number {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return (
     Number(args.pr ||
     envs.SYSTEM_PULLREQUEST_PULLREQUESTNUMBER ||
@@ -53,7 +53,7 @@ export function getServiceName(): string {
 }
 
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   let commit = envs.BUILD_SOURCEVERSION || ''
 
   if (_getPR(inputs)) {
@@ -73,12 +73,12 @@ function _getSHA(inputs: UploaderInputs): string {
 }
 
 function _getProject(inputs: UploaderInputs): string {
-  const { envs } = inputs
+  const { environment: envs } = inputs
   return envs.SYSTEM_TEAMPROJECT || ''
 }
 
 function _getServerURI(inputs: UploaderInputs): string {
-  const { envs } = inputs
+  const { environment: envs } = inputs
   return envs.SYSTEM_TEAMFOUNDATIONSERVERURI || ''
 }
 
@@ -98,7 +98,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     project: _getProject(inputs),
     server_uri: _getServerURI(inputs),
diff --git a/src/ci_providers/provider_bitbucket.ts b/src/ci_providers/provider_bitbucket.ts
index a6990d0..161713b 100644
--- a/src/ci_providers/provider_bitbucket.ts
+++ b/src/ci_providers/provider_bitbucket.ts
@@ -7,7 +7,7 @@ export function detect(envs: UploaderEnvs): boolean {
 }
 
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.BITBUCKET_BUILD_NUMBER || ''
 }
 
@@ -18,7 +18,7 @@ function _getBuildURL(inputs: UploaderInputs): string {
 }
 
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.branch || envs.BITBUCKET_BRANCH || ''
 }
 
@@ -27,7 +27,7 @@ function _getJob(envs: UploaderEnvs): string {
 }
 
 function _getPR(inputs: UploaderInputs): number {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return Number(args.pr || envs.BITBUCKET_PR_ID || '')
 }
 
@@ -40,7 +40,7 @@ export function getServiceName(): string {
 }
 
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   let commit = envs.BITBUCKET_COMMIT || ''
 
   if (commit && validateSHA(commit, 12)) {
@@ -51,7 +51,7 @@ function _getSHA(inputs: UploaderInputs): string {
 }
 
 function _getSlug(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
 
   let slug = ''
   if (envs.BITBUCKET_REPO_OWNER && envs.BITBUCKET_REPO_SLUG) {
@@ -66,7 +66,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_buildkite.ts b/src/ci_providers/provider_buildkite.ts
index e2918d0..23e9778 100644
--- a/src/ci_providers/provider_buildkite.ts
+++ b/src/ci_providers/provider_buildkite.ts
@@ -1,5 +1,4 @@
-import { logAndThrow } from '../helpers/util'
-import { UploaderInputs, IServiceParams, UploaderEnvs } from '../types'
+import { IServiceParams, UploaderEnvs, UploaderInputs } from '../types'
 
 /**
  * Detects if this CI provider is being used
@@ -18,7 +17,7 @@ export function detect(envs: UploaderEnvs): boolean {
  * @returns {string}
  */
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.BUILDKITE_BUILD_NUMBER || ''
 }
 
@@ -30,7 +29,7 @@ function _getBuild(inputs: UploaderInputs): string {
  */
 // eslint-disable-next-line no-unused-vars
 function _getBuildURL(inputs: UploaderInputs): string {
-  return inputs.envs.BUILDKITE_BUILD_URL || ''
+  return inputs.environment.BUILDKITE_BUILD_URL || ''
 }
 
 /**
@@ -40,7 +39,7 @@ function _getBuildURL(inputs: UploaderInputs): string {
  * @returns {string}
  */
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.branch || envs.BUILDKITE_BRANCH || ''
 }
 
@@ -89,12 +88,11 @@ export function getServiceName(): string {
  * @returns {string}
  */
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   if (Boolean(args.sha) || Boolean(envs.BUILDKITE_COMMIT)) {
     return args.sha || envs.BUILDKITE_COMMIT || ''
   }
-  logAndThrow('Unable to detect sha, please set manually with the -C flag')
-  return ''
+  throw new Error('Unable to detect sha, please set manually with the -C flag')
 }
 /**
  * Determine the slug (org/repo) based on  args or envs
@@ -103,11 +101,11 @@ function _getSHA(inputs: UploaderInputs): string {
  * @returns {string}
  */
 function _getSlug(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   if (args.slug || envs.BUILDKITE_PROJECT_SLUG) {
     return args.slug || envs.BUILDKITE_PROJECT_SLUG || ''
   }
-  logAndThrow('Unable to detect sluh, please set manually with the -r flag')
+  throw new Error('Unable to detect slug, please set manually with the -r flag')
   return ''
 }
 /**
@@ -122,7 +120,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_circleci.ts b/src/ci_providers/provider_circleci.ts
index 77d151c..cf11294 100644
--- a/src/ci_providers/provider_circleci.ts
+++ b/src/ci_providers/provider_circleci.ts
@@ -1,5 +1,4 @@
-import { logAndThrow } from '../helpers/util'
-import { UploaderInputs, IServiceParams, UploaderEnvs } from '../types'
+import { IServiceParams, UploaderEnvs, UploaderInputs } from '../types'
 
 export function detect(envs: UploaderEnvs): boolean {
   return Boolean(envs.CI) && Boolean(envs.CIRCLECI)
@@ -21,17 +20,17 @@ export function getServiceName(): string {
 }
 
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.branch || envs.CIRCLE_BRANCH || ''
 }
 
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.sha || envs.CIRCLE_SHA1 || ''
 }
 
 function _getSlug(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   let slug = args.slug || ''
   if (slug !== '') {
     return slug
@@ -42,7 +41,7 @@ function _getSlug(inputs: UploaderInputs): string {
     if (envs.CIRCLE_REPOSITORY_URL) {
       slug = `${envs.CIRCLE_REPOSITORY_URL.split(':')[1].split('.git')[0]}`
     } else {
-      logAndThrow(
+      throw new Error(
         'Unable to detect slug from env. Please set manually with the -r flag',
       )
     }
@@ -51,12 +50,12 @@ function _getSlug(inputs: UploaderInputs): string {
 }
 
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.CIRCLE_BUILD_NUM || ''
 }
 
 function _getPR(inputs: UploaderInputs): number {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return Number(args.pr || envs.CIRCLE_PR_NUMBER || '')
 }
 
@@ -70,7 +69,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_cirrus.ts b/src/ci_providers/provider_cirrus.ts
index e01be9c..7538a43 100644
--- a/src/ci_providers/provider_cirrus.ts
+++ b/src/ci_providers/provider_cirrus.ts
@@ -5,7 +5,7 @@ export function detect(envs: UploaderEnvs): boolean {
 }
 
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.CIRRUS_BUILD_ID || ''
 }
 
@@ -15,7 +15,7 @@ function _getBuildURL(inputs: UploaderInputs): string {
 }
 
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.branch || envs.CIRRUS_BRANCH || ''
 }
 
@@ -24,7 +24,7 @@ function _getJob(envs: UploaderEnvs): string {
 }
 
 function _getPR(inputs: UploaderInputs): number {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return Number(args.pr || envs.CIRRUS_PR || '')
 }
 
@@ -37,12 +37,12 @@ export function getServiceName(): string {
 }
 
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.sha || envs.CIRRUS_CHANGE_IN_REPO || ''
 }
 
 function _getSlug(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.slug || envs.CIRRUS_REPO_FULL_NAME || ''
 }
 
@@ -52,7 +52,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_codebuild.ts b/src/ci_providers/provider_codebuild.ts
index 4b4ee11..e9c2131 100644
--- a/src/ci_providers/provider_codebuild.ts
+++ b/src/ci_providers/provider_codebuild.ts
@@ -5,7 +5,7 @@ export function detect(envs: UploaderEnvs): boolean {
 }
 
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.CODEBUILD_BUILD_ID || ''
 }
 
@@ -15,7 +15,7 @@ function _getBuildURL(inputs: UploaderInputs): string {
 }
 
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return (
     args.branch ||
     (envs.CODEBUILD_WEBHOOK_HEAD_REF
@@ -29,7 +29,7 @@ function _getJob(envs: UploaderEnvs): string {
 }
 
 function _getPR(inputs: UploaderInputs): number {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return (
     Number(args.pr ||
     (envs.CODEBUILD_SOURCE_VERSION &&
@@ -48,12 +48,12 @@ export function getServiceName(): string {
 }
 
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.sha || envs.CODEBUILD_RESOLVED_SOURCE_VERSION || ''
 }
 
 function _getSlug(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return (
     args.slug ||
     (envs.CODEBUILD_SOURCE_REPO_URL
@@ -70,7 +70,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_drone.ts b/src/ci_providers/provider_drone.ts
index fc0dd5c..5f548ed 100644
--- a/src/ci_providers/provider_drone.ts
+++ b/src/ci_providers/provider_drone.ts
@@ -5,17 +5,17 @@ export function detect(envs: UploaderEnvs): boolean {
 }
 
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.DRONE_BUILD_NUMBER || ''
 }
 
 function _getBuildURL(inputs: UploaderInputs): string {
-  const { envs } = inputs
+  const { environment: envs } = inputs
   return envs.DRONE_BUILD_URL || ''
 }
 
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.branch || envs.DRONE_BRANCH || ''
 }
 
@@ -25,7 +25,7 @@ function _getJob(envs: UploaderEnvs): string {
 }
 
 function _getPR(inputs: UploaderInputs): number {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return Number(args.pr || envs.DRONE_PULL_REQUEST || '')
 }
 
@@ -38,12 +38,12 @@ export function getServiceName(): string {
 }
 
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.sha || envs.DRONE_COMMIT_SHA || ''
 }
 
 function _getSlug(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.slug || envs.DRONE_REPO_LINK || ''
 }
 
@@ -53,7 +53,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_githubactions.ts b/src/ci_providers/provider_githubactions.ts
index e45fef9..866655a 100644
--- a/src/ci_providers/provider_githubactions.ts
+++ b/src/ci_providers/provider_githubactions.ts
@@ -8,12 +8,12 @@ export function detect(envs: UploaderEnvs): boolean {
 }
 
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.GITHUB_RUN_ID || ''
 }
 
 function _getBuildURL(inputs: UploaderInputs): string {
-  const { envs } = inputs
+  const { environment: envs } = inputs
   return encodeURIComponent(
     `${envs.GITHUB_SERVER_URL}/${_getSlug(inputs)}/actions/runs/${_getBuild(
       inputs,
@@ -22,7 +22,7 @@ function _getBuildURL(inputs: UploaderInputs): string {
 }
 
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   const branchRegex = /refs\/heads\/(.*)/
   const branchMatches = branchRegex.exec(envs.GITHUB_REF || '')
   let branch
@@ -41,7 +41,7 @@ function _getJob(envs: UploaderEnvs): string {
 }
 
 function _getPR(inputs: UploaderInputs): number {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   let match
   if (envs.GITHUB_HEAD_REF && envs.GITHUB_HEAD_REF !== '') {
     const prRegex = /refs\/pull\/([0-9]+)\/merge/
@@ -62,7 +62,7 @@ export function getServiceName(): string {
 }
 
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   const pr = _getPR(inputs)
 
   let commit = envs.GITHUB_SHA
@@ -87,7 +87,7 @@ function _getSHA(inputs: UploaderInputs): string {
 }
 
 function _getSlug(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.slug || envs.GITHUB_REPOSITORY || ''
 }
 
@@ -97,7 +97,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_gitlabci.ts b/src/ci_providers/provider_gitlabci.ts
index 949d85e..89ccb75 100644
--- a/src/ci_providers/provider_gitlabci.ts
+++ b/src/ci_providers/provider_gitlabci.ts
@@ -7,7 +7,7 @@ export function detect(envs: UploaderEnvs): boolean {
 }
 
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.CI_BUILD_ID || envs.CI_JOB_ID || ''
 }
 
@@ -17,7 +17,7 @@ function _getBuildURL(inputs: UploaderInputs): string {
 }
 
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.branch || envs.CI_BUILD_REF_NAME || envs.CI_COMMIT_REF_NAME || ''
 }
 
@@ -40,12 +40,12 @@ export function getServiceName(): string {
 }
 
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.sha || envs.CI_BUILD_REF || envs.CI_COMMIT_SHA || ''
 }
 
 function _getSlug(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   const remoteAddr = envs.CI_BUILD_REPO || envs.CI_REPOSITORY_URL || ''
   return (
     args.slug ||
@@ -61,7 +61,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_jenkinsci.ts b/src/ci_providers/provider_jenkinsci.ts
index efabc52..a918be9 100644
--- a/src/ci_providers/provider_jenkinsci.ts
+++ b/src/ci_providers/provider_jenkinsci.ts
@@ -6,17 +6,17 @@ export function detect(envs: UploaderEnvs): boolean {
 }
 
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.BUILD_NUMBER || ''
 }
 
 function _getBuildURL(inputs: UploaderInputs): string {
-  const { envs } = inputs
+  const { environment: envs } = inputs
   return envs.BUILD_URL ? encodeURIComponent(envs.BUILD_URL) : ''
 }
 
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return (
     args.branch ||
     envs.ghprbSourceBranch ||
@@ -32,7 +32,7 @@ function _getJob(envs: UploaderEnvs) {
 }
 
 function _getPR(inputs: UploaderInputs): number {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return Number(args.pr || envs.ghprbPullId || envs.CHANGE_ID || '')
 }
 
@@ -45,7 +45,7 @@ export function getServiceName(): string {
 }
 
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.sha || envs.ghprbActualCommit || envs.GIT_COMMIT || ''
 }
 
@@ -60,7 +60,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_local.ts b/src/ci_providers/provider_local.ts
index 9317cfc..177636b 100644
--- a/src/ci_providers/provider_local.ts
+++ b/src/ci_providers/provider_local.ts
@@ -1,6 +1,5 @@
 import childprocess from 'child_process'
 import { parseSlug } from '../helpers/git'
-import { logAndThrow } from '../helpers/util'
 import { IServiceParams, UploaderEnvs, UploaderInputs } from '../types'
 
 export function detect(envs: UploaderEnvs): boolean {
@@ -29,8 +28,9 @@ function _getBranch(inputs: UploaderInputs): string {
       .trimRight()
     return branchName
   } catch (error) {
-    logAndThrow(`There was an error getting the branch name from git: ${error}`)
-    return ''
+    throw new Error(
+      `There was an error getting the branch name from git: ${error}`,
+    )
   }
 }
 
@@ -67,8 +67,7 @@ function _getSHA(inputs: UploaderInputs) {
       .trimRight()
     return sha
   } catch (error) {
-    logAndThrow(`There was an error getting the commit SHA from git: ${error}`)
-    return ''
+    throw new Error(`There was an error getting the commit SHA from git: ${error}`)
   }
 }
 
@@ -84,8 +83,7 @@ function _getSlug(inputs: UploaderInputs): string {
       .trimRight()
     return parseSlug(slug)
   } catch (error) {
-    logAndThrow(`There was an error getting the slug from git: ${error}`)
-    return ''
+    throw new Error(`There was an error getting the slug from git: ${error}`)
   }
 }
 
@@ -95,7 +93,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_teamcity.ts b/src/ci_providers/provider_teamcity.ts
index afad56b..96e628f 100644
--- a/src/ci_providers/provider_teamcity.ts
+++ b/src/ci_providers/provider_teamcity.ts
@@ -21,12 +21,12 @@ export function getServiceName(): string {
 }
 
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.branch || envs.BRANCH_NAME || ''
 }
 
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.sha || envs.BUILD_VCS_NUMBER || ''
 }
 
@@ -36,7 +36,7 @@ function _getSlug(inputs: UploaderInputs): string {
 }
 
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.BUILD_NUMBER || ''
 }
 
@@ -56,7 +56,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_template.js b/src/ci_providers/provider_template.js
index 5769c6b..c5feecf 100644
--- a/src/ci_providers/provider_template.js
+++ b/src/ci_providers/provider_template.js
@@ -5,8 +5,6 @@
  * @returns boolean
  */
 
-const { logAndThrow } = require('../helpers/util')
-
 // eslint-disable-next-line no-unused-vars
 function detect(envs) {
   return false
@@ -45,7 +43,9 @@ function _getBranch(inputs) {
   try {
     return args.branch || ''
   } catch (error) {
-    logAndThrow(`There was an error getting the branch name from git: ${error}`)
+    throw new Error(
+      `There was an error getting the branch name from git: ${error}`,
+    )
   }
 }
 
@@ -72,7 +72,7 @@ function _getPR(inputs) {
   try {
     return args.pr || ''
   } catch (error) {
-    logAndThrow(`There was an error getting the pr number: ${error}`)
+    throw new Error(`There was an error getting the pr number: ${error}`)
   }
 }
 
@@ -104,7 +104,9 @@ function _getSHA(inputs) {
   try {
     return args.sha || ''
   } catch (error) {
-    logAndThrow(`There was an error getting the commit SHA from git: ${error}`)
+    throw new Error(
+      `There was an error getting the commit SHA from git: ${error}`,
+    )
   }
 }
 /**
@@ -118,7 +120,7 @@ function _getSlug(inputs) {
   try {
     return args.slug || ''
   } catch (error) {
-    logAndThrow(`There was an error getting the slug from git: ${error}`)
+    throw new Error(`There was an error getting the slug from git: ${error}`)
   }
 }
 /**
diff --git a/src/ci_providers/provider_travisci.ts b/src/ci_providers/provider_travisci.ts
index b56cf18..fe0fdf3 100644
--- a/src/ci_providers/provider_travisci.ts
+++ b/src/ci_providers/provider_travisci.ts
@@ -5,7 +5,7 @@ export function detect(envs: UploaderEnvs): boolean {
 }
 
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.TRAVIS_JOB_NUMBER || ''
 }
 
@@ -15,7 +15,7 @@ function _getBuildURL(inputs: UploaderInputs): string {
 }
 
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
 
   let branch = ''
   if (envs.TRAVIS_BRANCH !== envs.TRAVIS_TAG) {
@@ -29,7 +29,7 @@ function _getJob(envs: UploaderEnvs): string {
 }
 
 function _getPR(inputs: UploaderInputs): number {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return Number(args.pr || envs.TRAVIS_PULL_REQUEST || '')
 }
 
@@ -42,12 +42,12 @@ export function getServiceName(): string {
 }
 
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.sha || envs.TRAVIS_PULL_REQUEST_SHA || envs.TRAVIS_COMMIT || ''
 }
 
 function _getSlug(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.slug || envs.TRAVIS_REPO_SLUG || ''
 }
 
@@ -57,7 +57,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/ci_providers/provider_wercker.ts b/src/ci_providers/provider_wercker.ts
index ac16418..c1363f9 100644
--- a/src/ci_providers/provider_wercker.ts
+++ b/src/ci_providers/provider_wercker.ts
@@ -5,17 +5,17 @@ export function detect(envs: UploaderEnvs): boolean {
 }
 
 function _getBuild(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.build || envs.WERCKER_MAIN_PIPELINE_STARTED || ''
 }
 
 function _getBuildURL(inputs: UploaderInputs): string {
-  const { envs } = inputs
+  const { environment: envs } = inputs
   return envs.WERCKER_BUILD_URL || ''
 }
 
 function _getBranch(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
 
   return args.branch || envs.WERCKER_GIT_BRANCH || ''
 }
@@ -39,12 +39,12 @@ export function getServiceName(): string {
 }
 
 function _getSHA(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.sha || envs.WERCKER_GIT_COMMIT || ''
 }
 
 function _getSlug(inputs: UploaderInputs): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   return args.slug || `${envs.WERCKER_GIT_OWNER}/${envs.WERCKER_GIT_REPOSITORY}`
 }
 
@@ -54,7 +54,7 @@ export function getServiceParams(inputs: UploaderInputs): IServiceParams {
     build: _getBuild(inputs),
     buildURL: _getBuildURL(inputs),
     commit: _getSHA(inputs),
-    job: _getJob(inputs.envs),
+    job: _getJob(inputs.environment),
     pr: _getPR(inputs),
     service: _getService(),
     slug: _getSlug(inputs),
diff --git a/src/helpers/cli.ts b/src/helpers/cli.ts
new file mode 100644
index 0000000..f28236b
--- /dev/null
+++ b/src/helpers/cli.ts
@@ -0,0 +1,145 @@
+export interface ICLIArgument {
+  name: string
+  alias: string
+  type?: string
+  default?: string | boolean
+  description: string
+}
+
+const args: ICLIArgument[] = [
+  {
+    alias: 'b',
+    name: 'build',
+    description: 'Specify the build number manually',
+  },
+  {
+    alias: 'B',
+    name: 'branch',
+    description: 'Specify the branch manually',
+  },
+  {
+    alias: 'e',
+    name: 'env',
+    description:
+      'Specify environment variables to be included with this build.\nAlso accepting environment variables: CODECOV_ENV=VAR,VAR2',
+  },
+  {
+    alias: 'C',
+    name: 'sha',
+    description: 'Specify the commit SHA mannually',
+  },
+  {
+    alias: 'f',
+    name: 'file',
+    description: 'Target file(s) to upload',
+  },
+  {
+    alias: 'F',
+    name: 'flags',
+    default: '',
+    description: 'Flag the upload to group coverage metrics',
+  },
+  {
+    alias: 'n',
+    name: 'name',
+    default: '',
+    description: 'Custom defined name of the upload. Visible in Codecov UI',
+  },
+  {
+    alias: 'N',
+    name: 'parent',
+    description:
+      "The commit SHA of the parent for which you are uploading coverage. If not present, the parent will be determined using the API of your repository provider. When using the repository provider's API, the parent is determined via finding the closest ancestor to the commit.",
+  },
+  {
+    alias: 'P',
+    name: 'pr',
+    description: 'Specify the pull request number mannually',
+  },
+  {
+    alias: 's',
+    name: 'dir',
+    description:
+      'Directory to search for coverage reports.\nAlready searches project root and current working directory',
+  },
+  {
+    alias: 't',
+    name: 'token',
+    default: '',
+    description: 'Codecov upload token',
+  },
+  {
+    alias: 'T',
+    name: 'tag',
+    default: '',
+    description: 'Specify the git tag',
+  },
+  {
+    alias: 'v',
+    name: 'verbose',
+    type: 'boolean',
+    description: 'Run with verbose logging',
+  },
+  {
+    alias: 'R',
+    name: 'rootDir',
+    description: 'Specify the project root directory when not in a git repo',
+  },
+  {
+    alias: 'Z',
+    name: 'nonZero',
+    type: 'boolean',
+    default: false,
+    description: 'Should errors exit with a non-zero (default: false)',
+  },
+  {
+    alias: 'd',
+    name: 'dryRun',
+    type: 'boolean',
+    description: "Don't upload files to Codecov",
+  },
+  {
+    alias: 'r',
+    name: 'slug',
+    description: 'Specify the slug manually (Enterprise use)',
+  },
+  {
+    alias: 'u',
+    name: 'url',
+    type: 'string',
+    description: 'Change the upload host (Enterprise use)',
+    default: 'https://codecov.io',
+  },
+  {
+    alias: 'c',
+    name: 'clean',
+    type: 'boolean',
+    default: false,
+    description: 'Move discovered coverage reports to the trash',
+  },
+  {
+    alias: 'X',
+    name: 'feature',
+    type: 'string',
+    description: `Toggle functionalities
+      -X network       Disable uploading the file network`,
+  },
+  {
+    alias: 'Q',
+    name: 'source',
+    type: 'string',
+    default: '',
+    description: `Used internally by Codecov, this argument helps track wrappers
+      of the uploader (e.g. GitHub Action, CircleCI Orb)`,
+  },
+]
+
+export interface IYargsObject {
+  option: (arg0: string, arg1: ICLIArgument) => void
+}
+
+export function addArguments(yargsInstance: IYargsObject): void {
+  args.forEach(arg => {
+    yargsInstance.option(arg.name, arg)
+  })
+}
diff --git a/src/helpers/files.ts b/src/helpers/files.ts
index fe8335b..5f10f68 100644
--- a/src/helpers/files.ts
+++ b/src/helpers/files.ts
@@ -1,12 +1,10 @@
-import { UploaderArgs } from '../types'
-
 import childProcess from 'child_process'
-import fs from 'fs'
 import glob from 'fast-glob'
+import fs from 'fs'
+import { readFile } from 'fs/promises'
 import { posix as path } from 'path'
-import { logAndThrow } from './util'
+import { UploaderArgs } from '../types'
 import { logError, verbose } from './logger'
-import { readFile } from 'fs/promises'
 
 export const MARKER_NETWORK_END = '<<<<<< network\n'
 export const MARKER_FILE_END = '<<<<<< EOF\n'
@@ -139,6 +137,7 @@ export function globBlacklist(): string[] {
     'phpunit-coverage.xml',
     'remapInstanbul.coverage*.json',
     'scoverage.measurements.*',
+    'test-result-*-codecoverage.json',
     'test_*_coverage.txt',
     'testrunner-coverage*',
   ]
@@ -183,10 +182,7 @@ export async function getCoverageFiles(
 
   return glob(coverageFilePatterns.map(globstar), {
     cwd: projectRoot,
-    ignore: [
-      ...manualBlacklist(),
-      ...globBlacklist(),
-    ],
+    ignore: [...manualBlacklist(), ...globBlacklist()],
   })
 }
 
@@ -198,8 +194,7 @@ export function fetchGitRoot(): string {
       }).stdout || process.cwd()
     ).trimRight()
   } catch (error) {
-    logAndThrow('Error fetching git root. Please try using the -R flag.')
-    return '.'
+    throw new Error('Error fetching git root. Please try using the -R flag.')
   }
 }
 
@@ -215,7 +210,7 @@ export function parseGitIgnore(projectRoot: string): string[] {
   try {
     lines = readAllLines(gitIgnorePath) || []
   } catch (error) {
-    logAndThrow(`Unable to open ${gitIgnorePath}: ${error}`)
+    throw new Error(`Unable to open ${gitIgnorePath}: ${error}`)
   }
 
   return lines.filter(line => {
@@ -240,10 +235,12 @@ export function getAllFiles(
 ): string[] {
   verbose(`Searching for files in ${dirPath}`, Boolean(args.verbose))
 
-  return glob.sync(['**/*', '**/.[!.]*'], {
-    cwd: projectRoot,
-    ignore: globBlacklist(),
-  }).map((file) => `${file}\n`)
+  return glob
+    .sync(['**/*', '**/.[!.]*'], {
+      cwd: projectRoot,
+      ignore: globBlacklist(),
+    })
+    .map(file => `${file}\n`)
 }
 
 /**
@@ -271,7 +268,7 @@ export async function readCoverageFile(
   return readFile(getFilePath(projectRoot, filePath), {
     encoding: 'utf-8',
   }).catch(err => {
-    logAndThrow(`There was an error reading the coverage file: ${err}`)
+    throw new Error(`There was an error reading the coverage file: ${err}`)
   })
 }
 
diff --git a/src/helpers/git.ts b/src/helpers/git.ts
index 0068403..af17711 100644
--- a/src/helpers/git.ts
+++ b/src/helpers/git.ts
@@ -1,5 +1,4 @@
 import childProcess from 'child_process'
-import { logAndThrow } from './util'
 
 export function parseSlug(slug: string): string {
   // origin    https://github.com/torvalds/linux.git (fetch)
@@ -19,8 +18,7 @@ export function parseSlug(slug: string): string {
     const cleanSlug = slug.split(':')[1].replace('.git', '')
     return cleanSlug
   }
-  logAndThrow(`Unable to parse slug URL: ${slug}`)
-  return ''
+  throw new Error(`Unable to parse slug URL: ${slug}`)
 }
 
 export function parseSlugFromRemoteAddr(remoteAddr?: string): string {
diff --git a/src/helpers/token.ts b/src/helpers/token.ts
index 03207a3..6413705 100644
--- a/src/helpers/token.ts
+++ b/src/helpers/token.ts
@@ -12,7 +12,7 @@ import { validateToken } from './validate'
  * @returns string
  */
 export function getToken(inputs: UploaderInputs, projectRoot: string): string {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   const options = [
     [args.token, 'arguments'],
     [envs.CODECOV_TOKEN, 'environment variables'],
diff --git a/src/helpers/util.ts b/src/helpers/util.ts
deleted file mode 100644
index 0500226..0000000
--- a/src/helpers/util.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { logError } from './logger'
-
-/**
- * Log the error and throw it
- * @param {string} message
- * @throws Error
- */
-export function logAndThrow(message: string): never {
-  logError(message)
-  throw new Error(message)
-}
diff --git a/src/helpers/validate.ts b/src/helpers/validate.ts
index bdbb245..8826d13 100644
--- a/src/helpers/validate.ts
+++ b/src/helpers/validate.ts
@@ -1,7 +1,5 @@
-import { UploaderArgs } from '../types'
-
 import validator from 'validator'
-import { logAndThrow } from './util'
+import { UploaderArgs } from '../types'
 
 /**
  *
@@ -61,9 +59,14 @@ export function fetchToken(args: UploaderArgs): string {
   return token
 }
 
-export function checkValueType(name: string, value: unknown, type: string): void {
+export function checkValueType(
+  name: string,
+  value: unknown,
+  type: string,
+): void {
   if (typeof value !== type) {
-    return logAndThrow(`The value of ${name} is not of type ${type}, can not continue, please review: ${value}`)
+    throw new Error(
+      `The value of ${name} is not of type ${type}, can not continue, please review: ${value}`,
+    )
   }
 }
-
diff --git a/src/helpers/web.ts b/src/helpers/web.ts
index c21e2d6..d23ccc7 100644
--- a/src/helpers/web.ts
+++ b/src/helpers/web.ts
@@ -1,10 +1,10 @@
-import { IServiceParams, UploaderInputs } from '../types'
-
+import { snakeCase } from "snake-case";
 import superagent from 'superagent'
+
 import { version } from '../../package.json'
-import * as validateHelpers from './validate'
+import { IServiceParams, UploaderInputs } from '../types'
 import { info, logError } from './logger'
-import { logAndThrow } from './util'
+import * as validateHelpers from './validate'
 import { checkValueType } from './validate'
 
 /**
@@ -18,14 +18,14 @@ export function populateBuildParams(
   inputs: UploaderInputs,
   serviceParams: IServiceParams,
 ): IServiceParams {
-  const { args, envs } = inputs
+  const { args, environment: envs } = inputs
   serviceParams.name = args.name || envs.CODECOV_NAME || ''
   serviceParams.tag = args.tag || ''
   let flags: string[]
   if (typeof args.flags === 'object') {
     flags = [...args.flags]
   } else {
-    flags = [args.flags]
+    flags = [args.flags || '']
   }
   serviceParams.flags = flags
     .filter(flag => validateHelpers.validateFlags(flag))
@@ -45,7 +45,7 @@ export function getPackage(source: string): string {
 export async function uploadToCodecovPUT(
   uploadURL: string,
   uploadFile: string | Buffer,
-): Promise<{ status: string, resultURL: string }> {
+): Promise<{ status: string; resultURL: string }> {
   info('Uploading...')
 
   const parts = uploadURL.split('\n')
@@ -63,11 +63,9 @@ export async function uploadToCodecovPUT(
     if (result.status === 200) {
       return { status: 'success', resultURL: codecovResultURL }
     }
-    logAndThrow(
-      `Error uploading during PUT (inner): ${result.status}, ${result.body}`,
-    )
+    throw new Error(`${result.status}, ${result.body}`)
   } catch (error) {
-    logAndThrow(`Error uploading during PUT (outer): ${error}`)
+    throw new Error(`Error PUTing file to storage: ${error}`)
   }
 }
 
@@ -91,14 +89,11 @@ export async function uploadToCodecov(
       )}&token=${token}&${query}`,
     )
     .retry()
-    .send(uploadFile)
-    .set('Content-Type', 'text/plain')
-    .set('Content-Encoding', 'gzip')
     .set('X-Upload-Token', token)
     .set('X-Reduced-Redundancy', 'false')
     .on('error', err => {
       logError(
-        `Error uploading to Codecov when fetching PUT (inner): ${err.status} ${err.response.text}`,
+        `Error POSTing to ${uploadURL}: ${err.status} ${err.response.text}`,
       )
     })
     .ok(res => res.status === 200)
@@ -106,25 +101,7 @@ export async function uploadToCodecov(
   if (result.res) {
     return result.res.text
   }
-  logAndThrow(`We don't have a PUT URL`)
-}
-
-/**
- *
- * @param {string} str
- * @returns {string}
- */
-function camelToSnake(str: string): string {
-  return (
-    str &&
-    (
-      str.match(
-        /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g,
-      ) || []
-    )
-      .map((s: string) => s.toLowerCase())
-      .join('_')
-  )
+  throw new Error(`There was an error fetching the storage URL during POST`)
 }
 
 /**
@@ -138,7 +115,6 @@ export function generateQuery(queryParams: IServiceParams): string {
     queryParams.pr = ''
   }
   return Object.entries(queryParams)
-    .map(([key, value]) => `${camelToSnake(key)}=${value}`)
+    .map(([key, value]) => `${snakeCase(key)}=${value}`)
     .join('&')
 }
-
diff --git a/src/index.ts b/src/index.ts
index d753a33..1d44ef6 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,4 +1,4 @@
-import { UploaderArgs } from './types'
+import { UploaderArgs, UploaderInputs } from './types'
 
 import zlib from 'zlib'
 import { version } from '../package.json'
@@ -6,7 +6,6 @@ import * as validateHelpers from './helpers/validate'
 import * as webHelpers from './helpers/web'
 import { info, verbose } from './helpers/logger'
 import providers from './ci_providers'
-import { logAndThrow } from './helpers/util'
 import { getToken } from './helpers/token'
 import {
   coverageFilePatterns,
@@ -89,7 +88,7 @@ export async function main(
   // TODO: clean and sanitize envs and args
   const envs = process.env
   // args
-  const inputs = { args, envs }
+  const inputs: UploaderInputs = { args, environment: envs }
 
   let uploadHost: string
   if (args.url && validateHelpers.validateURL(args.url)) {
@@ -125,7 +124,7 @@ export async function main(
     try {
       fileListing = await getFileListing(projectRoot, args)
     } catch (error) {
-      logAndThrow(`Error getting file listing: ${error}`)
+      throw new Error(`Error getting file listing: ${error}`)
     }
 
     uploadFile = uploadFile.concat(fileListing).concat(MARKER_NETWORK_END)
@@ -150,8 +149,7 @@ export async function main(
 
   // Remove invalid and duplicate file paths
   coverageFilePaths = [... new Set(coverageFilePaths.filter(file => {
-    return validateHelpers.validateFileNamePath(file) &&
-      fileExists(args.dir || projectRoot, file)
+    return fileExists(args.dir || projectRoot, file)
   }))]
 
   if (coverageFilePaths.length > 0) {
@@ -161,7 +159,7 @@ export async function main(
     const noFilesError = args.file ?
       'No coverage files found, exiting.' :
       'No coverage files located, please try use `-f`, or change the project root with `-R`'
-    logAndThrow(noFilesError)
+    throw new Error(noFilesError)
   }
 
   verbose('End of network processing', Boolean(args.verbose))
@@ -190,7 +188,7 @@ export async function main(
     coverageFileAdded = true
   }
   if (!coverageFileAdded) {
-    logAndThrow( 'No coverage files could be found to upload, exiting.')
+    throw new Error( 'No coverage files could be found to upload, exiting.')
   }
 
   // Cleanup
@@ -233,8 +231,7 @@ export async function main(
   }
 
   if (serviceParams === undefined) {
-    logAndThrow('Unable to detect service, please specify manually.')
-    process.exit(args.nonZero ? -1 : 0)
+    throw new Error('Unable to detect service, please specify manually.')
   }
 
   // == Step 8: either upload or dry-run
@@ -287,7 +284,7 @@ export async function main(
     info(JSON.stringify(result))
     return result
   } catch (error) {
-    logAndThrow(`Error uploading to ${uploadHost}: ${error}`)
+    throw new Error(`Error uploading to ${uploadHost}: ${error}`)
   }
 }
 
diff --git a/src/types.ts b/src/types.ts
index 0a6da8a..0e0277f 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -5,7 +5,7 @@ export interface UploaderArgs {
   env?: string // Specify environment variables to be included with this build
   sha?: string // Specify the commit SHA mannually
   file?: string | string[] // Target file(s) to upload
-  flags: string | string[] // Flag the upload to group coverage metrics
+  flags?: string | string[] // Flag the upload to group coverage metrics
   name?: string // Custom defined name of the upload. Visible in Codecov UI
   parent?: string // The commit SHA of the parent for which you are uploading coverage.
   pr?: string // Specify the pull request number mannually
@@ -25,7 +25,7 @@ export interface UploaderArgs {
 export type UploaderEnvs = NodeJS.Dict<string>
 
 export interface UploaderInputs {
-  envs: UploaderEnvs
+  environment: UploaderEnvs
   args: UploaderArgs
 }
 
diff --git a/tsconfig.json b/tsconfig.json
index ba999fb..e7b8fa5 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -12,5 +12,5 @@
     "resolveJsonModule": true,
     "skipLibCheck": true
   },
-  "exclude": ["test/*"]
+  "exclude": ["dist/*", "test/*"]
 }


Test patch:
diff --git a/test/helpers/cli.test.ts b/test/helpers/cli.test.ts
new file mode 100644
index 0000000..5af1afe
--- /dev/null
+++ b/test/helpers/cli.test.ts
@@ -0,0 +1,17 @@
+import { addArguments, IYargsObject } from '../../src/helpers/cli'
+
+describe('CLI Helper', () => {
+  it('should be able to add arguments to the "yargsObject: it is passed', () => {
+    const fakeYargs: IYargsObject = {
+      option: jest.fn(),
+    }
+
+    addArguments(fakeYargs)
+
+    expect(fakeYargs.option).toBeCalledWith('build', {
+      alias: 'b',
+      description: 'Specify the build number manually',
+      name: 'build',
+    })
+  })
+})
diff --git a/test/helpers/token.test.ts b/test/helpers/token.test.ts
index 0313ae9..196afed 100644
--- a/test/helpers/token.test.ts
+++ b/test/helpers/token.test.ts
@@ -2,6 +2,7 @@ import path from 'path'
 
 import * as fileHelpers from '../../src/helpers/files'
 import * as tokenHelpers from '../../src/helpers/token'
+import { UploaderInputs } from '../../src/types'
 
 describe('Get tokens', () => {
   const fixturesDir = path.join(
@@ -52,33 +53,33 @@ describe('Get tokens', () => {
 
   describe('From right source', () => {
     it('Returns from args', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: { token: 'argtoken', flags: '' },
-        envs: { CODECOV_TOKEN: 'envtoken' },
+        environment: { CODECOV_TOKEN: 'envtoken' },
       }
       expect(tokenHelpers.getToken(inputs, fixturesDir)).toBe('argtoken')
     })
 
     it('Returns from env', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: { flags: '' },
-        envs: { CODECOV_TOKEN: 'envtoken' },
+        environment: { CODECOV_TOKEN: 'envtoken' },
       }
       expect(tokenHelpers.getToken(inputs, fixturesDir)).toBe('envtoken')
     })
 
     it('Returns from env', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: { flags: '' },
-        envs: {},
+        environment: {},
       }
       expect(tokenHelpers.getToken(inputs, fixturesDir)).toBe('faketoken')
     })
 
     it('Returns from no source', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: { flags: '' },
-        envs: {},
+        environment: {},
       }
       expect(tokenHelpers.getToken(inputs, '.')).toBe('')
     })
diff --git a/test/helpers/web.test.ts b/test/helpers/web.test.ts
index 9df8c03..a6079f5 100644
--- a/test/helpers/web.test.ts
+++ b/test/helpers/web.test.ts
@@ -94,7 +94,7 @@ describe('Web Helpers', () => {
 
   it('can populateBuildParams() from args', () => {
     const result = webHelper.populateBuildParams(
-      { args: { flags: 'testFlag', tag: 'testTag' }, envs: {} },
+      { args: { flags: 'testFlag', tag: 'testTag' }, environment: {} },
       {
         name: '',
         tag: ', flags: []',
@@ -113,7 +113,7 @@ describe('Web Helpers', () => {
 
   it('can populateBuildParams() from args with multiple flags', () => {
     const result = webHelper.populateBuildParams(
-      { args: { flags: ['testFlag1', 'testFlag2'], tag: 'testTag' }, envs: {} },
+      { args: { flags: ['testFlag1', 'testFlag2'], tag: 'testTag' }, environment: {} },
       {
         name: '',
         tag: ', flags: []',
diff --git a/test/providers/index.test.ts b/test/providers/index.test.ts
index 596cfdf..dd32ffe 100644
--- a/test/providers/index.test.ts
+++ b/test/providers/index.test.ts
@@ -1,21 +1,22 @@
 import td from 'testdouble'
 
 import providers from '../../src/ci_providers'
+import { UploaderInputs } from '../../src/types'
 
 describe('CI Providers', () => {
   afterEach(() => {
     td.reset()
   })
 
-  it('is an array of CI providers', () =>
+  describe('check that each provider', () =>
     expect(providers).toBeInstanceOf(Array))
   providers.forEach(provider => {
-    it('has a service name', () => {
+    it(`${provider.getServiceName()} has a service name`, () => {
       expect(typeof provider.getServiceName()).toBe('string')
       expect(provider.getServiceName()).not.toBe('')
     })
 
-    it('has env var names', () => {
+    it(`${provider.getServiceName()} has env var names`, () => {
       const envVarNames = provider.getEnvVarNames()
       expect(typeof envVarNames).toBe('object')
       expect(envVarNames.length).toBeGreaterThan(0)
@@ -23,5 +24,26 @@ describe('CI Providers', () => {
         expect(typeof envVarName).toBe('string')
       }
     })
+
+    describe(`${provider.getServiceName()} can return a ISeviceParams object that`, () => {
+      const inputs: UploaderInputs = {
+        args: {
+          sha: '123',
+          slug: 'testOrg/testRepo'
+        },
+        environment: {}
+      }
+
+      const serviceParams = provider.getServiceParams(inputs)
+      expect(serviceParams).not.toBeNull()
+
+      it('has a sha', () => {
+        expect(serviceParams.commit).toEqual(inputs.args.sha)
+      })
+
+      it('has a slug', () => {
+        expect(serviceParams.slug).toEqual(inputs.args.slug)
+      })
+    })
   })
 })
diff --git a/test/providers/provider_appveyorci.test.ts b/test/providers/provider_appveyorci.test.ts
index af45bc6..479f938 100644
--- a/test/providers/provider_appveyorci.test.ts
+++ b/test/providers/provider_appveyorci.test.ts
@@ -17,38 +17,38 @@ describe('AppveyorCI Params', () => {
           source: '',
           flags: '',
         },
-        envs: {},
+        environment: {},
       }
-      let detected = providerAppveyorci.detect(inputs.envs)
+      let detected = providerAppveyorci.detect(inputs.environment)
       expect(detected).toBeFalsy()
 
-      inputs.envs.CI = 'true'
-      detected = providerAppveyorci.detect(inputs.envs)
+      inputs.environment.CI = 'true'
+      detected = providerAppveyorci.detect(inputs.environment)
       expect(detected).toBeFalsy()
 
-      inputs.envs.CI = 'True'
-      detected = providerAppveyorci.detect(inputs.envs)
+      inputs.environment.CI = 'True'
+      detected = providerAppveyorci.detect(inputs.environment)
       expect(detected).toBeFalsy()
 
-      inputs.envs.CI = 'false'
-      inputs.envs.APPVEYOR = 'true'
-      detected = providerAppveyorci.detect(inputs.envs)
+      inputs.environment.CI = 'false'
+      inputs.environment.APPVEYOR = 'true'
+      detected = providerAppveyorci.detect(inputs.environment)
       expect(detected).toBeFalsy()
 
-      inputs.envs.APPVEYOR = 'True'
-      detected = providerAppveyorci.detect(inputs.envs)
+      inputs.environment.APPVEYOR = 'True'
+      detected = providerAppveyorci.detect(inputs.environment)
       expect(detected).toBeFalsy()
     })
 
     it('does run with AppveyorCI env variable', () => {
-      const inputs = {
+      const inputs : UploaderInputs= {
         args: {},
-        envs: {
+        environment: {
           CI: 'true',
           APPVEYOR: 'true',
         },
       }
-      const detected = providerAppveyorci.detect(inputs.envs)
+      const detected = providerAppveyorci.detect(inputs.environment)
       expect(detected).toBeTruthy()
     })
   })
@@ -61,7 +61,7 @@ describe('AppveyorCI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         APPVEYOR: 'true',
         APPVEYOR_ACCOUNT_NAME: 'testOrg',
         APPVEYOR_BUILD_ID: '2',
@@ -101,7 +101,7 @@ describe('AppveyorCI Params', () => {
         slug: 'testOrg/testRepo',
         flags: '',
       },
-      envs: {
+      environment: {
         APPVEYOR: 'true',
         CI: 'true',
       },
diff --git a/test/providers/provider_azurepipelines.test.ts b/test/providers/provider_azurepipelines.test.ts
index 0110ac8..1e0bd53 100644
--- a/test/providers/provider_azurepipelines.test.ts
+++ b/test/providers/provider_azurepipelines.test.ts
@@ -18,9 +18,9 @@ describe('Jenkins CI Params', () => {
           source: '',
           flags: '',
         },
-        envs: {},
+        environment: {},
       }
-      const detected = providerAzurepipelines.detect(inputs.envs)
+      const detected = providerAzurepipelines.detect(inputs.environment)
       expect(detected).toBeFalsy()
     })
 
@@ -32,11 +32,11 @@ describe('Jenkins CI Params', () => {
           source: '',
           flags: '',
         },
-        envs: {
+        environment: {
           SYSTEM_TEAMFOUNDATIONSERVERURI: 'true',
         },
       }
-      const detected = providerAzurepipelines.detect(inputs.envs)
+      const detected = providerAzurepipelines.detect(inputs.environment)
       expect(detected).toBeTruthy()
     })
   })
@@ -49,7 +49,7 @@ describe('Jenkins CI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         BUILD_BUILDNUMBER: '1',
         BUILD_BUILDID: '2',
         BUILD_SOURCEBRANCH: 'refs/heads/main',
@@ -85,7 +85,7 @@ describe('Jenkins CI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         BUILD_BUILDNUMBER: '1',
         BUILD_BUILDID: '2',
         BUILD_SOURCEBRANCH: 'refs/heads/main',
@@ -121,7 +121,7 @@ describe('Jenkins CI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         BUILD_BUILDNUMBER: '1',
         BUILD_BUILDID: '2',
         BUILD_SOURCEBRANCH: 'refs/heads/main',
@@ -168,7 +168,7 @@ describe('Jenkins CI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         SYSTEM_TEAMFOUNDATIONSERVERURI: 'https://example.azure.com',
       },
     }
diff --git a/test/providers/provider_bitbucket.test.ts b/test/providers/provider_bitbucket.test.ts
index d0cfe0b..085b70b 100644
--- a/test/providers/provider_bitbucket.test.ts
+++ b/test/providers/provider_bitbucket.test.ts
@@ -17,25 +17,25 @@ describe('Bitbucket Params', () => {
           source: '',
           flags: '',
         },
-        envs: {},
+        environment: {},
       }
-      let detected = providerBitbucket.detect(inputs.envs)
+      let detected = providerBitbucket.detect(inputs.environment)
       expect(detected).toBeFalsy()
 
-      inputs.envs['CI'] = 'true'
-      detected = providerBitbucket.detect(inputs.envs)
+      inputs.environment['CI'] = 'true'
+      detected = providerBitbucket.detect(inputs.environment)
       expect(detected).toBeFalsy()
     })
 
     it('does not run without Bitbucket env variable', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: {},
-        envs: {
+        environment: {
           BITBUCKET_BUILD_NUMBER: '1',
           CI: 'true',
         },
       }
-      const detected = providerBitbucket.detect(inputs.envs)
+      const detected = providerBitbucket.detect(inputs.environment)
       expect(detected).toBeTruthy()
     })
   })
@@ -48,7 +48,7 @@ describe('Bitbucket Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         BITBUCKET_BUILD_NUMBER: '1',
         CI: 'true',
       },
@@ -75,7 +75,7 @@ describe('Bitbucket Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         BITBUCKET_BRANCH: 'main',
         BITBUCKET_BUILD_NUMBER: '1',
         BITBUCKET_COMMIT: 'testingsha',
@@ -107,7 +107,7 @@ describe('Bitbucket Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         BITBUCKET_BRANCH: 'main',
         BITBUCKET_BUILD_NUMBER: '1',
         BITBUCKET_COMMIT: 'testingsha',
@@ -138,7 +138,7 @@ describe('Bitbucket Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         BITBUCKET_BRANCH: 'main',
         BITBUCKET_BUILD_NUMBER: '1',
         BITBUCKET_COMMIT: 'testingsha12',
@@ -179,7 +179,7 @@ describe('Bitbucket Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         BITBUCKET_BRANCH: 'main',
         BITBUCKET_BUILD_NUMBER: '1',
         BITBUCKET_COMMIT: 'testingsha',
diff --git a/test/providers/provider_buildkite.test.ts b/test/providers/provider_buildkite.test.ts
index cdf8941..8ee9023 100644
--- a/test/providers/provider_buildkite.test.ts
+++ b/test/providers/provider_buildkite.test.ts
@@ -18,13 +18,13 @@ describe('Buildkite Params', () => {
     })
 
     it('does not run without Buildkite env variable', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: {},
-        envs: {
+        environment: {
           BUILDKITE: 'true',
         },
       }
-      const detected = providerBuildkite.detect(inputs.envs)
+      const detected = providerBuildkite.detect(inputs.environment)
       expect(detected).toBeTruthy()
     })
   })
@@ -37,7 +37,7 @@ describe('Buildkite Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         BUILDKITE: 'true',
         BUILDKITE_BUILD_NUMBER: '1',
         BUILDKITE_JOB_ID: '3',
@@ -75,7 +75,7 @@ describe('Buildkite Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         BUILDKITE: 'true',
         CI: 'true',
       },
diff --git a/test/providers/provider_circleci.test.ts b/test/providers/provider_circleci.test.ts
index 9f945fa..2fe4618 100644
--- a/test/providers/provider_circleci.test.ts
+++ b/test/providers/provider_circleci.test.ts
@@ -1,7 +1,7 @@
 import td from 'testdouble'
 
 import * as providerCircleci from '../../src/ci_providers//provider_circleci'
-import { IServiceParams } from '../../src/types'
+import { IServiceParams, UploaderInputs } from '../../src/types'
 
 describe('CircleCI Params', () => {
   afterEach(() => {
@@ -10,33 +10,33 @@ describe('CircleCI Params', () => {
 
   describe('detect()', () => {
     it('does not run without CircleCI env variable', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: {},
-        envs: {},
+        environment: {},
       }
-      const detected = providerCircleci.detect(inputs.envs)
+      const detected = providerCircleci.detect(inputs.environment)
       expect(detected).toBeFalsy()
     })
 
     it('does run with CircleCI env variable', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: {},
-        envs: {
+        environment: {
           CI: 'true',
           CIRCLECI: 'true',
         },
       }
-      const detected = providerCircleci.detect(inputs.envs)
+      const detected = providerCircleci.detect(inputs.environment)
       expect(detected).toBeTruthy()
     })
   })
 
   it('gets correct params', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         CIRCLECI: 'true',
         CIRCLE_BRANCH: 'master',
@@ -64,11 +64,11 @@ describe('CircleCI Params', () => {
   })
 
   it('gets correct slug when empty reponame', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         CIRCLECI: 'true',
         CIRCLE_BRANCH: 'master',
diff --git a/test/providers/provider_cirrus.test.ts b/test/providers/provider_cirrus.test.ts
index f12c4fe..7b23221 100644
--- a/test/providers/provider_cirrus.test.ts
+++ b/test/providers/provider_cirrus.test.ts
@@ -12,21 +12,21 @@ describe('Cirrus Params', () => {
     it('does not run without Cirrus env variable', () => {
       const inputs = {
         args: {},
-        envs: {},
+        environment: {},
       }
-      const detected = providerCirrus.detect(inputs.envs)
+      const detected = providerCirrus.detect(inputs.environment)
       expect(detected).toBeFalsy()
     })
 
     it('does run with Cirrus env variable', () => {
       const inputs = {
         args: {},
-        envs: {
+        environment: {
           CI: 'true',
           CIRRUS_CI: 'true',
         },
       }
-      const detected = providerCirrus.detect(inputs.envs)
+      const detected = providerCirrus.detect(inputs.environment)
       expect(detected).toBeTruthy()
     })
   })
@@ -39,7 +39,7 @@ describe('Cirrus Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         CIRRUS_CI: 'true',
         CIRRUS_BRANCH: 'master',
@@ -76,7 +76,7 @@ describe('Cirrus Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         CIRRUS_CI: 'true',
         CIRRUS_BRANCH: 'master',
diff --git a/test/providers/provider_codebuild.test.ts b/test/providers/provider_codebuild.test.ts
index 6b9332c..7dd2266 100644
--- a/test/providers/provider_codebuild.test.ts
+++ b/test/providers/provider_codebuild.test.ts
@@ -26,26 +26,26 @@ describe('CodeBuild Params', () => {
           url: '',
           flags: '',
         },
-        envs: {
+        environment: {
           CI: 'true',
           CODEBUILD_CI: 'true',
         },
       }
-      const detected = providerCodeBuild.detect(inputs.envs)
+      const detected = providerCodeBuild.detect(inputs.environment)
       expect(detected).toBeTruthy()
     })
   })
 
   describe('getServiceParams()', () => {
     it('gets correct params', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: {
           tag: '',
           source: '',
           url: '',
           flags: '',
         },
-        envs: {
+        environment: {
           CI: 'true',
           CODEBUILD_CI: 'true',
           CODEBUILD_WEBHOOK_HEAD_REF: 'refs/heads/master',
@@ -70,7 +70,7 @@ describe('CodeBuild Params', () => {
     })
 
     it('gets correct params for overrides', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: {
           branch: 'branch',
           build: '3',
@@ -82,7 +82,7 @@ describe('CodeBuild Params', () => {
           url: '',
           flags: '',
         },
-        envs: {
+        environment: {
           CI: 'true',
           CODEBUILD_CI: 'true',
           CODEBUILD_WEBHOOK_HEAD_REF: 'refs/heads/master',
diff --git a/test/providers/provider_drone.test.ts b/test/providers/provider_drone.test.ts
index 91e93c1..a371437 100644
--- a/test/providers/provider_drone.test.ts
+++ b/test/providers/provider_drone.test.ts
@@ -39,7 +39,7 @@ describe('Drone Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         DRONE: 'true',
         DRONE_BRANCH: 'master',
diff --git a/test/providers/provider_githubactions.test.ts b/test/providers/provider_githubactions.test.ts
index c41fb1b..71b7c1a 100644
--- a/test/providers/provider_githubactions.test.ts
+++ b/test/providers/provider_githubactions.test.ts
@@ -15,7 +15,7 @@ describe('GitHub Actions Params', () => {
         args: {
           flags: '',
         },
-        envs: {
+        environment: {
           GITHUB_REF: 'refs/heads/master',
           GITHUB_REPOSITORY: 'testOrg/testRepo',
           GITHUB_RUN_ID: '2',
@@ -23,7 +23,7 @@ describe('GitHub Actions Params', () => {
           GITHUB_WORKFLOW: 'testWorkflow',
         },
       }
-      const detected = providerGitHubactions.detect(inputs.envs)
+      const detected = providerGitHubactions.detect(inputs.environment)
       expect(detected).toBeFalsy()
     })
 
@@ -47,7 +47,7 @@ describe('GitHub Actions Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         GITHUB_ACTIONS: 'true',
         GITHUB_REF: 'refs/heads/master',
         GITHUB_REPOSITORY: 'testOrg/testRepo',
@@ -80,7 +80,7 @@ describe('GitHub Actions Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         GITHUB_ACTIONS: 'true',
         GITHUB_HEAD_REF: 'branch',
         GITHUB_REF: 'refs/pull/1/merge',
@@ -121,7 +121,7 @@ describe('GitHub Actions Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         GITHUB_ACTIONS: 'true',
         GITHUB_HEAD_REF: 'branch',
         GITHUB_REF: 'refs/pull/1/merge',
@@ -168,7 +168,7 @@ describe('GitHub Actions Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         GITHUB_ACTIONS: 'true',
         GITHUB_SERVER_URL: 'https://github.com',
       },
@@ -201,7 +201,7 @@ describe('GitHub Actions Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         GITHUB_ACTIONS: 'true',
         GITHUB_HEAD_REF: 'branch',
         GITHUB_REF: 'refs/pull/1/merge',
diff --git a/test/providers/provider_gitlabci.test.ts b/test/providers/provider_gitlabci.test.ts
index 3a81e67..25fa937 100644
--- a/test/providers/provider_gitlabci.test.ts
+++ b/test/providers/provider_gitlabci.test.ts
@@ -34,14 +34,14 @@ describe('GitLabCI Params', () => {
   })
 
   it('gets correct empty params', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         tag: '',
         url: '',
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         GITLAB_CI: 'true',
       },
     }
@@ -64,14 +64,14 @@ describe('GitLabCI Params', () => {
   })
 
   it('gets correct initial params', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         tag: '',
         url: '',
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI_BUILD_ID: '1',
         CI_BUILD_REF: 'testingsha',
         CI_BUILD_REF_NAME: 'main',
@@ -104,7 +104,7 @@ describe('GitLabCI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI_COMMIT_REF_NAME: 'master',
         CI_COMMIT_SHA: 'testsha',
         CI_JOB_ID: '2',
@@ -134,25 +134,25 @@ describe('GitLabCI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         GITLAB_CI: 'true',
       },
     }
 
     it('can get the slug from http', () => {
-      inputs.envs.CI_BUILD_REPO = 'https://gitlab.com/testOrg/testRepo.git'
+      inputs.environment.CI_BUILD_REPO = 'https://gitlab.com/testOrg/testRepo.git'
       const params = providerGitLabci.getServiceParams(inputs)
       expect(params.slug).toBe('testOrg/testRepo')
     })
 
     it('can get the slug from git url', () => {
-      inputs.envs.CI_BUILD_REPO = 'git@gitlab.com:testOrg/testRepo.git'
+      inputs.environment.CI_BUILD_REPO = 'git@gitlab.com:testOrg/testRepo.git'
       const params = providerGitLabci.getServiceParams(inputs)
       expect(params.slug).toBe('testOrg/testRepo')
     })
 
     it('can get the slug from git config', () => {
-      inputs.envs.CI_BUILD_REPO = ''
+      inputs.environment.CI_BUILD_REPO = ''
       const spawnSync = td.replace(childProcess, 'spawnSync')
       td.when(
         spawnSync('git', ['config', '--get', 'remote.origin.url']),
@@ -163,7 +163,7 @@ describe('GitLabCI Params', () => {
     })
 
     it('can get the slug from git config as /', () => {
-      inputs.envs.CI_BUILD_REPO = ''
+      inputs.environment.CI_BUILD_REPO = ''
       const spawnSync = td.replace(childProcess, 'spawnSync')
       td.when(
         spawnSync('git', ['config', '--get', 'remote.origin.url']),
@@ -174,7 +174,7 @@ describe('GitLabCI Params', () => {
     })
 
     it('can handle no remote origin url', () => {
-      inputs.envs.CI_BUILD_REPO = ''
+      inputs.environment.CI_BUILD_REPO = ''
       const spawnSync = td.replace(childProcess, 'spawnSync')
       td.when(
         spawnSync('git', ['config', '--get', 'remote.origin.url']),
@@ -198,7 +198,7 @@ describe('GitLabCI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         GITLAB_CI: 'true',
       },
     }
diff --git a/test/providers/provider_jenkinsci.test.ts b/test/providers/provider_jenkinsci.test.ts
index 7760aa7..ea530b7 100644
--- a/test/providers/provider_jenkinsci.test.ts
+++ b/test/providers/provider_jenkinsci.test.ts
@@ -18,13 +18,13 @@ describe('Jenkins CI Params', () => {
           source: '',
           flags: '',
         },
-        envs: {},
+        environment: {},
       }
-      let detected = providerJenkinsci.detect(inputs.envs)
+      let detected = providerJenkinsci.detect(inputs.environment)
       expect(detected).toBeFalsy()
 
-      inputs.envs.JENKINS_URL = ''
-      detected = providerJenkinsci.detect(inputs.envs)
+      inputs.environment.JENKINS_URL = ''
+      detected = providerJenkinsci.detect(inputs.environment)
       expect(detected).toBeFalsy()
     })
 
@@ -48,7 +48,7 @@ describe('Jenkins CI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         BUILD_NUMBER: '1',
         BUILD_URL: 'https://example.jenkins.com',
         CHANGE_ID: '2',
@@ -83,7 +83,7 @@ describe('Jenkins CI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         BUILD_NUMBER: '1',
         BUILD_URL: 'https://example.jenkins.com',
         CHANGE_ID: '2',
@@ -114,7 +114,7 @@ describe('Jenkins CI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         JENKINS_URL: 'https://example.com',
       },
     }
diff --git a/test/providers/provider_local.test.ts b/test/providers/provider_local.test.ts
index d3ae1c5..2dbbcb7 100644
--- a/test/providers/provider_local.test.ts
+++ b/test/providers/provider_local.test.ts
@@ -18,11 +18,11 @@ describe('Local Params', () => {
           source: '',
           flags: '',
         },
-        envs: {
+        environment: {
           CI: 'true',
         },
       }
-      const detected = providerLocal.detect(inputs.envs)
+      const detected = providerLocal.detect(inputs.environment)
       expect(detected).toBeFalsy()
     })
 
@@ -34,15 +34,15 @@ describe('Local Params', () => {
           source: '',
           flags: '',
         },
-        envs: {},
+        environment: {},
       }
-      const detected = providerLocal.detect(inputs.envs)
+      const detected = providerLocal.detect(inputs.environment)
       expect(detected).toBeTruthy()
     })
   })
 
   it('returns on override args', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         branch: 'main',
         pr: '1',
@@ -53,7 +53,7 @@ describe('Local Params', () => {
         source: '',
         flags: '',
       },
-      envs: {},
+      environment: {},
     }
     const expected: IServiceParams = {
       branch: 'main',
@@ -70,14 +70,14 @@ describe('Local Params', () => {
   })
 
   it('returns errors on git command failures', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         tag: '',
         url: '',
         source: '',
         flags: '',
       },
-      envs: {},
+      environment: {},
     }
     const spawnSync = td.replace(childProcess, 'spawnSync')
     expect(() => {
@@ -102,14 +102,14 @@ describe('Local Params', () => {
   })
 
   describe('getSlug()', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         tag: '',
         url: '',
         source: '',
         flags: '',
       },
-      envs: {},
+      environment: {},
     }
 
     it('can get the slug from a git url', () => {
diff --git a/test/providers/provider_teamcity.test.ts b/test/providers/provider_teamcity.test.ts
index a66d0d4..689b5d9 100644
--- a/test/providers/provider_teamcity.test.ts
+++ b/test/providers/provider_teamcity.test.ts
@@ -2,7 +2,7 @@ import td from 'testdouble'
 import childProcess from 'child_process'
 
 import * as providerTeamCity from '../../src/ci_providers/provider_teamcity'
-import { IServiceParams } from '../../src/types'
+import { IServiceParams, UploaderInputs } from '../../src/types'
 
 describe('TeamCity Params', () => {
   afterEach(() => {
@@ -11,40 +11,40 @@ describe('TeamCity Params', () => {
 
   describe('detect()', () => {
     it('does not run without TeamCity env variable', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: {},
-        envs: {},
+        environment: {},
       }
-      const detected = providerTeamCity.detect(inputs.envs)
+      const detected = providerTeamCity.detect(inputs.environment)
       expect(detected).toBeFalsy()
     })
 
     it('does run with TeamCity env variable', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: {
           tag: '',
           url: '',
           source: '',
         },
-        envs: {
+        environment: {
           CI: 'true',
           TEAMCITY_VERSION: 'true',
         },
       }
-      const detected = providerTeamCity.detect(inputs.envs)
+      const detected = providerTeamCity.detect(inputs.environment)
       expect(detected).toBeTruthy()
     })
   })
 
   it('gets correct params', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         tag: '',
         url: '',
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         TEAMCITY_VERSION: 'true',
         BRANCH_NAME: 'main',
@@ -71,14 +71,14 @@ describe('TeamCity Params', () => {
   })
 
   it('gets correct params and remote slug', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         tag: '',
         url: '',
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         TEAMCITY_VERSION: 'true',
         BRANCH_NAME: 'main',
@@ -105,7 +105,7 @@ describe('TeamCity Params', () => {
   })
 
   it('gets correct params for overrides', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         branch: 'branch',
         build: '3',
@@ -117,7 +117,7 @@ describe('TeamCity Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         TEAMCITY_VERSION: 'true',
         BRANCH_NAME: 'main',
diff --git a/test/providers/provider_template.test.ts b/test/providers/provider_template.test.ts
index 4080861..081f2d0 100644
--- a/test/providers/provider_template.test.ts
+++ b/test/providers/provider_template.test.ts
@@ -14,9 +14,9 @@ describe('<Ci> Params', () => {
 
   describe('detect()', () => {
     it('does not run without <Ci> env variable', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: {},
-        envs: {},
+        environment: {},
       }
       /*
       const detected = provider<Ci>.detect(inputs.envs)
@@ -25,9 +25,9 @@ describe('<Ci> Params', () => {
     })
 
     it('does not run without <Ci> env variable', () => {
-      const inputs = {
+      const inputs: UploaderInputs= {
         args: {},
-        envs: {},
+        environment: {},
       }
       /*
       const detected = provider<Ci>.detect(inputs.envs)
@@ -40,7 +40,7 @@ describe('<Ci> Params', () => {
   it('gets the correct params on no env variables', () => {
     const inputs: UploaderInputs = {
       args: { tag: '', url: '', source: '', flags: '' },
-      envs: {},
+      environment: {},
     }
     const expected: IServiceParams = {
       branch: '',
@@ -62,7 +62,7 @@ describe('<Ci> Params', () => {
   it('gets the correct params on push', () => {
     const inputs: UploaderInputs = {
       args: { tag: '', url: '', source: '', flags: '' },
-      envs: {},
+      environment: {},
     }
     const expected: IServiceParams = {
       branch: '',
@@ -89,7 +89,7 @@ describe('<Ci> Params', () => {
         source: '',
         flags: '',
       },
-      envs: {},
+      environment: {},
     }
     const expected: IServiceParams = {
       branch: '',
@@ -116,7 +116,7 @@ describe('<Ci> Params', () => {
         source: '',
         flags: '',
       },
-      envs: {},
+      environment: {},
     }
     const expected: IServiceParams = {
       branch: '',
diff --git a/test/providers/provider_travisci.test.ts b/test/providers/provider_travisci.test.ts
index e26fdd4..b4240e3 100644
--- a/test/providers/provider_travisci.test.ts
+++ b/test/providers/provider_travisci.test.ts
@@ -17,46 +17,46 @@ describe('TravisCI Params', () => {
           source: '',
           flags: '',
         },
-        envs: {},
+        environment: {},
       }
-      let detected = providerTravisci.detect(inputs.envs)
+      let detected = providerTravisci.detect(inputs.environment)
       expect(detected).toBeFalsy()
 
-      inputs.envs.CI = 'true'
-      detected = providerTravisci.detect(inputs.envs)
+      inputs.environment.CI = 'true'
+      detected = providerTravisci.detect(inputs.environment)
       expect(detected).toBeFalsy()
 
-      inputs.envs.TRAVIS = 'true'
-      detected = providerTravisci.detect(inputs.envs)
+      inputs.environment.TRAVIS = 'true'
+      detected = providerTravisci.detect(inputs.environment)
       expect(detected).toBeTruthy()
 
-      inputs.envs.SHIPPABLE = 'true'
-      detected = providerTravisci.detect(inputs.envs)
+      inputs.environment.SHIPPABLE = 'true'
+      detected = providerTravisci.detect(inputs.environment)
       expect(detected).toBeFalsy()
     })
 
     it('does run with TravisCI env variable', () => {
-      const inputs = {
+      const inputs: UploaderInputs = {
         args: {},
-        envs: {
+        environment: {
           CI: 'true',
           TRAVIS: 'true',
         },
       }
-      const detected = providerTravisci.detect(inputs.envs)
+      const detected = providerTravisci.detect(inputs.environment)
       expect(detected).toBeTruthy()
     })
   })
 
   it('gets correct params on push', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         tag: '',
         url: '',
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         TRAVIS: 'true',
         TRAVIS_JOB_NUMBER: '1',
@@ -83,14 +83,14 @@ describe('TravisCI Params', () => {
   })
 
   it('gets correct params on PR', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         tag: '',
         url: '',
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         TRAVIS: 'true',
         TRAVIS_BRANCH: 'branch',
@@ -119,14 +119,14 @@ describe('TravisCI Params', () => {
   })
 
   it('gets correct params on PR with no pull request branch', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         tag: '',
         url: '',
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         TRAVIS: 'true',
         TRAVIS_BRANCH: 'branch',
@@ -154,7 +154,7 @@ describe('TravisCI Params', () => {
   })
 
   it('gets correct params for overrides', () => {
-    const inputs = {
+    const inputs: UploaderInputs = {
       args: {
         branch: 'branch',
         build: '3',
@@ -166,7 +166,7 @@ describe('TravisCI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         TRAVIS: 'true',
       },
diff --git a/test/providers/provider_wercker.test.ts b/test/providers/provider_wercker.test.ts
index 1876ab7..1661024 100644
--- a/test/providers/provider_wercker.test.ts
+++ b/test/providers/provider_wercker.test.ts
@@ -14,9 +14,9 @@ describe('Wercker CI Params', () => {
         args: {
           flags: '',
         },
-        envs: {},
+        environment: {},
       }
-      const detected = providerWercker.detect(inputs.envs)
+      const detected = providerWercker.detect(inputs.environment)
       expect(detected).toBeFalsy()
     })
 
@@ -25,12 +25,12 @@ describe('Wercker CI Params', () => {
         args: {
           flags: '',
         },
-        envs: {
+        environment: {
           CI: 'true',
           WERCKER_MAIN_PIPELINE_STARTED: 'true',
         },
       }
-      const detected = providerWercker.detect(inputs.envs)
+      const detected = providerWercker.detect(inputs.environment)
       expect(detected).toBeTruthy()
     })
   })
@@ -43,7 +43,7 @@ describe('Wercker CI Params', () => {
         source: '',
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         WERCKER_MAIN_PIPELINE_STARTED: '1',
         WERCKER_GIT_BRANCH: 'main',
@@ -80,7 +80,7 @@ describe('Wercker CI Params', () => {
         slug: 'testOrg/testRepo',
         flags: '',
       },
-      envs: {
+      environment: {
         CI: 'true',
         WERCKER_MAIN_PIPELINE_STARTED: '1',
         WERCKER_GIT_BRANCH: 'main',
diff --git a/test/test_helpers.js b/test/test_helpers.js
index a0ecf09..4f8d09f 100644
--- a/test/test_helpers.js
+++ b/test/test_helpers.js
@@ -1,7 +1,6 @@
 const td = require('testdouble')
 const childProcess = require('child_process')
 const { beforeAll, afterEach, afterAll, expect } = require('@jest/globals')
-const { logAndThrow } = require('../src/helpers/util')
 
 // eslint-disable-next-line no-undef
 require('testdouble-jest')(td, jest)
@@ -17,12 +16,12 @@ let exec
 
 beforeAll(() => {
   execSync = jest.spyOn(childProcess, 'execSync').mockImplementation(() => {
-    logAndThrow(
+    throw new Error(
       `Security alert! Do not use execSync(), use spawnSync() instead`,
     )
   })
   exec = jest.spyOn(childProcess, 'exec').mockImplementation(() => {
-    logAndThrow(`Security alert! Do not use exec(), use spawn() instead`)
+    throw new Error(`Security alert! Do not use exec(), use spawn() instead`)
   })
 })