First draft
diff --git a/.eslintrc.json b/.eslintrc.json
index ef9fcf4..528d8da 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -14,6 +14,7 @@
     "project": "./tsconfig.eslint.json"
   },
   "rules": {
+    "@typescript-eslint/camelcase": ["off"]
   },
   "env": {
     "node": true,
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..ce4ac4d
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,18 @@
+name: "build-test"
+on: # rebuild any PRs and main branch changes
+  pull_request:
+  push:
+    branches:
+      - master
+      - 'feature/*'
+      - 'releases/*'
+
+jobs:
+  # make sure build/ci work properly
+  build:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - run: |
+        npm install
+        npm run all
diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml
new file mode 100644
index 0000000..1f82161
--- /dev/null
+++ b/.github/workflows/examples.yml
@@ -0,0 +1,252 @@
+name: "examples"
+on: [push]
+
+jobs:
+  # make sure the action works on a clean machines without building
+
+  ## Basic
+  test_basic_success:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test Basic Success
+        conclusion: success
+
+  test_basic_success_with_output:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test Basic Success (Implicit)
+        conclusion: success
+        output:
+          summary: Test was a success
+          text_description: |
+            This is a text description of the annotations and images
+            With more stuff
+            And more
+
+  test_basic_failure:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test Basic Failure
+        conclusion: failure
+
+  # Other codes
+  test_basic_neutral:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test 1 = Neutral
+        conclusion: neutral
+
+  test_basic_cancelled:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test Basic Cancelled
+        conclusion: cancelled
+
+  test_basic_timed_out:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test Basic Timed Out
+        conclusion: timed_out
+
+  test_basic_action_required:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test Basic Action Required
+        conclusion: action_required
+
+  ## Based on command
+  test_with_annotation:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test Advanced With Output
+        conclusion: success
+
+  ## With annotations
+  test_with_annotations:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test With Annotations
+        conclusion: success
+        output: # output.summary is required with annotations!
+          summary: Some warnings in README.md
+        annotations:
+          - path: README.md
+            annotation_level: warning
+            title: Spell Checker
+            message: Check your spelling for 'banaas'.
+            raw_details: Do you mean 'bananas' or 'banana'?
+            start_line: 1
+            end_line: 2
+
+  test_with_annotations_from_run:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - id: annotations
+      run: |
+        echo ::set-output name=value::{"path":"README.md","start_line":1,"end_line":2,"message":"Check your spelling for 'banaas'.","annotation_level":"warning"}
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test With Annotations From Run
+        conclusion: success
+        output: # output.summary is required with annotations!
+          summary: Some warnings in README.md
+        annotations: ${{ steps.annotations.outputs.value }}
+
+  ## With images
+  test_with_images:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test With Images
+        conclusion: success
+        output: # output.summary is required with images!
+          summary: Some cool pics
+        images:
+          - alt: Cool pic
+            image_url: https://via.placeholder.com/150
+            caption: Cool description
+
+  test_with_images_from_run:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - id: images
+      run: |
+        echo ::set-output name=value::{"alt":"Cool pic","image_url":"https://via.placeholder.com/150","caption":"Cool description"}
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test With Images From Run
+        conclusion: success
+        output: # output.summary is required with images!
+          summary: Some warnings in README.md
+        images: ${{ steps.images.outputs.value }}
+
+  ## With actions
+  # TODO: HOW DO WE SET THE WEBHOOK!
+  test_with_actions:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test With Actions
+        conclusion: success
+        actions:
+          - label: Click Me
+            description: Click me to get free RAM
+            identifier: sent_to_webhook
+
+  test_with_actions_from_run:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - id: actions
+      run: |
+        echo ::set-output name=value::{"label":"Click Me","description":"Click me to get free RAM","identifier":"sent_to_webhook"}
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test With Actions From Run
+        conclusion: success
+        # output.summary is required with actions!
+        output:
+          summary: Some warnings in README.md
+        actions: ${{ steps.actions.outputs.value }}
+
+  ## With init
+  test_with_init:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test With Init
+        status: in_progress
+    - run: sleep 30
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        status: completed
+        conclusion: failure
+
+  test_with_init_implicit:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test With Init (Implicit)
+        status: in_progress
+    - run: sleep 30
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        conclusion: failure
+
+  ## Based on job
+  test_based_job_success:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: ./
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test Based On Job (Success)
+        conclusion: ${{ job }}
+
+  test_based_job_failure:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - run: false
+    - uses: ./
+      if: always()
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        name: Test Based On Job (Failure)
+        conclusion: ${{ job }}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
deleted file mode 100644
index c058dd1..0000000
--- a/.github/workflows/test.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-name: "build-test"
-on: # rebuild any PRs and main branch changes
-  pull_request:
-  push:
-    branches:
-      - master
-      - 'releases/*'
-
-jobs:
-  # make sure build/ci work properly
-  build:
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@v1
-    - run: |
-        npm install
-        npm run all
-
-  # make sure the action works on a clean machines without building
-  test1:
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@v1
-    - uses: ./
-      with:
-        token: ${{ secrets.GITHUB_TOKEN }}
-
-  # TODO: add more (race conditions, failures, etc)
diff --git a/.prettierrc.json b/.prettierrc.json
index 9d64c21..bf0887a 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -1,8 +1,8 @@
 {
-  "printWidth": 80,
+  "printWidth": 120,
   "tabWidth": 2,
   "useTabs": false,
-  "semi": false,
+  "semi": true,
   "singleQuote": true,
   "trailingComma": "all",
   "bracketSpacing": false,
diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts
index 32cf034..bced80d 100644
--- a/__tests__/main.test.ts
+++ b/__tests__/main.test.ts
@@ -1,15 +1,15 @@
-import * as process from 'process'
-import * as cp from 'child_process'
-import * as path from 'path'
+import * as process from 'process';
+import * as cp from 'child_process';
+import * as path from 'path';
 
 // shows how the runner will run a javascript action with env / stdout protocol
 test('test runs', () => {
-  process.env['TOKEN'] = 'ABC'
-  const ip = path.join(__dirname, '..', 'lib', 'main.js')
+  process.env['TOKEN'] = 'ABC';
+  const ip = path.join(__dirname, '..', 'lib', 'main.js');
   const options: cp.ExecSyncOptions = {
     env: process.env,
-  }
-  console.log(cp.execSync(`node ${ip}`, options).toString())
-})
+  };
+  console.log(cp.execSync(`node ${ip}`, options).toString());
+});
 
 // TODO: add more
diff --git a/action.yml b/action.yml
index e7a778d..125221d 100644
--- a/action.yml
+++ b/action.yml
@@ -4,6 +4,29 @@
 inputs:
   token:
     description: 'your GITHUB_TOKEN'
+    required: true
+  name:
+    description: 'the name of your check'
+    required: true
+  conclusion:
+    description: 'the conclusion of your check'
+    required: true
+  status:
+    description: 'the status of your check'
+    required: false
+    default: completed
+  output:
+    description: 'the output of your check'
+    required: false
+  annotations:
+    description: 'the annotations of your check'
+    required: false
+  images:
+    description: 'the images of your check'
+    required: false
+  actions:
+    description: 'the actions of your check'
+    required: false
 runs:
   using: 'node12'
   main: 'dist/index.js'
diff --git a/dist/index.js b/dist/index.js
index 24aa44e..37237e3 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1 +1 @@
-module.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=require("os")},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(198)}return startup()}({87:function(e){e.exports=r(87)},198:function(e,t,r){"use strict";var n=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r(function(t){t(e)})}return new(r||(r=Promise))(function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())})};var i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(Object.hasOwnProperty.call(e,r))t[r]=e[r];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const u=i(r(470));const o=r(521);function run(){return n(this,void 0,void 0,function*(){try{const e=u.getInput("milliseconds");u.debug(`Waiting ${e} milliseconds ...`);u.debug((new Date).toTimeString());yield o.wait(parseInt(e,10));u.debug((new Date).toTimeString());u.setOutput("time",(new Date).toTimeString())}catch(e){u.setFailed(e.message)}})}run()},431:function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:true});const n=r(87);function issueCommand(e,t,r){const i=new Command(e,t,r);process.stdout.write(i.toString()+n.EOL)}t.issueCommand=issueCommand;function issue(e,t){issueCommand(e,{},t)}t.issue=issue;const i="##[";class Command{constructor(e,t,r){if(!e){e="missing.command"}this.command=e;this.properties=t;this.message=r}toString(){let e=i+this.command;if(this.properties&&Object.keys(this.properties).length>0){e+=" ";for(const t in this.properties){if(this.properties.hasOwnProperty(t)){const r=this.properties[t];if(r){e+=`${t}=${escape(`${r||""}`)};`}}}}e+="]";const t=`${this.message||""}`;e+=escapeData(t);return e}}function escapeData(e){return e.replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function escape(e){return e.replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/]/g,"%5D").replace(/;/g,"%3B")}},470:function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:true});const n=r(431);const i=r(622);var u;(function(e){e[e["Success"]=0]="Success";e[e["Failure"]=1]="Failure"})(u=t.ExitCode||(t.ExitCode={}));function exportVariable(e,t){process.env[e]=t;n.issueCommand("set-env",{name:e},t)}t.exportVariable=exportVariable;function exportSecret(e,t){exportVariable(e,t);n.issueCommand("set-secret",{},t)}t.exportSecret=exportSecret;function addPath(e){n.issueCommand("add-path",{},e);process.env["PATH"]=`${e}${i.delimiter}${process.env["PATH"]}`}t.addPath=addPath;function getInput(e,t){const r=process.env[`INPUT_${e.replace(" ","_").toUpperCase()}`]||"";if(t&&t.required&&!r){throw new Error(`Input required and not supplied: ${e}`)}return r.trim()}t.getInput=getInput;function setOutput(e,t){n.issueCommand("set-output",{name:e},t)}t.setOutput=setOutput;function setFailed(e){process.exitCode=u.Failure;error(e)}t.setFailed=setFailed;function debug(e){n.issueCommand("debug",{},e)}t.debug=debug;function error(e){n.issue("error",e)}t.error=error;function warning(e){n.issue("warning",e)}t.warning=warning},521:function(e,t){"use strict";var r=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r(function(t){t(e)})}return new(r||(r=Promise))(function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:true});function wait(e){return r(this,void 0,void 0,function*(){return new Promise(t=>{if(isNaN(e)){throw new Error("milliseconds not a number")}setTimeout(()=>t("done!"),e)})})}t.wait=wait},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=require("path")}});
\ No newline at end of file
+module.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=require("os")},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(429)}return startup()}({87:function(e){e.exports=r(87)},429:function(e,t,r){e.exports=function(e,t){"use strict";var r={};function __webpack_require__(t){if(r[t]){return r[t].exports}var n=r[t]={i:t,l:false,exports:{}};e[t].call(n.exports,n,n.exports,__webpack_require__);n.l=true;return n.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(198)}return startup()}({87:function(e){e.exports=r(87)},198:function(e,t,r){"use strict";var n=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r(function(t){t(e)})}return new(r||(r=Promise))(function(r,u){function fulfilled(e){try{step(n.next(e))}catch(e){u(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){u(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())})};var u=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(Object.hasOwnProperty.call(e,r))t[r]=e[r];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const i=u(r(470));const o=r(521);function run(){return n(this,void 0,void 0,function*(){try{const e=i.getInput("milliseconds");i.debug(`Waiting ${e} milliseconds ...`);i.debug((new Date).toTimeString());yield o.wait(parseInt(e,10));i.debug((new Date).toTimeString());i.setOutput("time",(new Date).toTimeString())}catch(e){i.setFailed(e.message)}})}run()},431:function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:true});const n=r(87);function issueCommand(e,t,r){const u=new Command(e,t,r);process.stdout.write(u.toString()+n.EOL)}t.issueCommand=issueCommand;function issue(e,t){issueCommand(e,{},t)}t.issue=issue;const u="##[";class Command{constructor(e,t,r){if(!e){e="missing.command"}this.command=e;this.properties=t;this.message=r}toString(){let e=u+this.command;if(this.properties&&Object.keys(this.properties).length>0){e+=" ";for(const t in this.properties){if(this.properties.hasOwnProperty(t)){const r=this.properties[t];if(r){e+=`${t}=${escape(`${r||""}`)};`}}}}e+="]";const t=`${this.message||""}`;e+=escapeData(t);return e}}function escapeData(e){return e.replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function escape(e){return e.replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/]/g,"%5D").replace(/;/g,"%3B")}},470:function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:true});const n=r(431);const u=r(622);var i;(function(e){e[e["Success"]=0]="Success";e[e["Failure"]=1]="Failure"})(i=t.ExitCode||(t.ExitCode={}));function exportVariable(e,t){process.env[e]=t;n.issueCommand("set-env",{name:e},t)}t.exportVariable=exportVariable;function exportSecret(e,t){exportVariable(e,t);n.issueCommand("set-secret",{},t)}t.exportSecret=exportSecret;function addPath(e){n.issueCommand("add-path",{},e);process.env["PATH"]=`${e}${u.delimiter}${process.env["PATH"]}`}t.addPath=addPath;function getInput(e,t){const r=process.env[`INPUT_${e.replace(" ","_").toUpperCase()}`]||"";if(t&&t.required&&!r){throw new Error(`Input required and not supplied: ${e}`)}return r.trim()}t.getInput=getInput;function setOutput(e,t){n.issueCommand("set-output",{name:e},t)}t.setOutput=setOutput;function setFailed(e){process.exitCode=i.Failure;error(e)}t.setFailed=setFailed;function debug(e){n.issueCommand("debug",{},e)}t.debug=debug;function error(e){n.issue("error",e)}t.error=error;function warning(e){n.issue("warning",e)}t.warning=warning},521:function(e,t){"use strict";var r=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r(function(t){t(e)})}return new(r||(r=Promise))(function(r,u){function fulfilled(e){try{step(n.next(e))}catch(e){u(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){u(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:true});function wait(e){return r(this,void 0,void 0,function*(){return new Promise(t=>{if(isNaN(e)){throw new Error("milliseconds not a number")}setTimeout(()=>t("done!"),e)})})}t.wait=wait},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=r(622)}})},622:function(e){e.exports=require("path")}});
\ No newline at end of file
diff --git a/jest.config.js b/jest.config.js
index 9bac3cc..f3a27fa 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -8,4 +8,4 @@
     '^.+\\.ts$': 'ts-jest',
   },
   verbose: true,
-}
+};
diff --git a/package.json b/package.json
index dfd516b..381c53c 100644
--- a/package.json
+++ b/package.json
@@ -6,10 +6,10 @@
   "main": "dist/index.js",
   "scripts": {
     "build": "tsc",
-    "lint": "eslint *.js **/*.ts",
+    "lint": "eslint '**/*.js' '**/*.ts'",
     "pack": "ncc build -m",
     "test": "jest",
-    "format": "prettier --write *.js **/*.ts",
+    "format": "prettier --write '**/*.js' '**/*.ts'",
     "all": "npm run build && npm run lint && npm run pack && npm test"
   },
   "repository": {
diff --git a/src/checks.ts b/src/checks.ts
new file mode 100644
index 0000000..8271217
--- /dev/null
+++ b/src/checks.ts
@@ -0,0 +1,69 @@
+import {GitHub} from '@actions/github';
+import * as Inputs from './namespaces/Inputs';
+
+type Ownership = {
+  owner: string;
+  repo: string;
+};
+
+type CreateOptions = {
+  completed: boolean;
+};
+
+const unpackInputs = (inputs: Inputs.Args): object => {
+  let output;
+  if (inputs.output) {
+    output = {
+      summary: inputs.output.summary,
+      text: inputs.output.text_description,
+      actions: inputs.actions,
+      images: inputs.images,
+    };
+  }
+  return {
+    status: inputs.status.toString(),
+    conclusion: inputs.conclusion.toString(),
+    output,
+    actions: inputs.actions,
+  };
+};
+
+const formatDate = (): string => {
+  return new Date().toISOString();
+};
+
+export const createRun = async (
+  octokit: GitHub,
+  sha: string,
+  ownership: Ownership,
+  inputs: Inputs.Args,
+  options?: CreateOptions,
+): Promise<number> => {
+  const dates: {completed_at?: string} = {};
+  if (!options || options.completed) {
+    dates.completed_at = formatDate();
+  }
+  const {data} = await octokit.checks.create({
+    ...ownership,
+    head_sha: sha,
+    name: inputs.name,
+    started_at: formatDate(),
+    ...dates,
+    ...unpackInputs(inputs),
+  });
+  return data.id;
+};
+
+export const updateRun = async (
+  octokit: GitHub,
+  id: number,
+  ownership: Ownership,
+  inputs: Inputs.Args,
+): Promise<void> => {
+  await octokit.checks.update({
+    ...ownership,
+    check_run_id: id,
+    completed_at: formatDate(),
+    ...unpackInputs(inputs),
+  });
+};
diff --git a/src/inputs.ts b/src/inputs.ts
new file mode 100644
index 0000000..6b5ed0d
--- /dev/null
+++ b/src/inputs.ts
@@ -0,0 +1,51 @@
+import {InputOptions} from '@actions/core';
+import * as Inputs from './namespaces/Inputs';
+
+type GetInput = (name: string, options?: InputOptions | undefined) => string;
+
+const parseJSON = <T>(getInput: GetInput, property: string): T | undefined => {
+  const value = getInput(property);
+  if (!value) {
+    return;
+  }
+  try {
+    const obj = JSON.parse(value);
+    return obj as T;
+  } catch (e) {
+    throw new Error(`invalid format for '${property}: ${e.toString()}`);
+  }
+};
+
+export const parseInputs = (getInput: GetInput): Inputs.Args => {
+  const token = getInput('token', {required: true});
+  const name = getInput('name', {required: true});
+  const statusStr = getInput('status', {required: true});
+  const conclusionStr = getInput('conclusion', {required: true});
+
+  if (!(statusStr in Inputs.Status)) {
+    throw new Error(`invalid value for 'status': '${statusStr}'`);
+  }
+  const status = statusStr as Inputs.Status;
+
+  if (!(conclusionStr in Inputs.Conclusion)) {
+    throw new Error(`invalid value for 'conclusion': '${conclusionStr}'`);
+  }
+  const conclusion = conclusionStr as Inputs.Conclusion;
+
+  const output = parseJSON<Inputs.Output>(getInput, 'output');
+  const annotations = parseJSON<Inputs.Annotations>(getInput, 'annotations');
+  const images = parseJSON<Inputs.Images>(getInput, 'images');
+  const actions = parseJSON<Inputs.Actions>(getInput, 'actions');
+
+  return {
+    name,
+    token,
+    status,
+    conclusion,
+
+    output,
+    annotations,
+    images,
+    actions,
+  };
+};
diff --git a/src/main.ts b/src/main.ts
index 0208cac..2a5ff19 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,44 +1,44 @@
-import * as core from '@actions/core'
-import * as github from '@actions/github'
+import * as core from '@actions/core';
+import * as github from '@actions/github';
+import {parseInputs} from './inputs';
+import {createRun, updateRun} from './checks';
 
-// eslint-disable-next-line @typescript-eslint/require-await
+const stateID = 'checkID';
+
 async function run(): Promise<void> {
   try {
-    const token: string = core.getInput('token')
+    core.debug(`Parsing inputs`);
+    const inputs = parseInputs(core.getInput);
 
-    core.debug(`Setting up OctoKit`)
-    const octokit = new github.GitHub(token)
+    core.debug(`Setting up OctoKit`);
+    const octokit = new github.GitHub(inputs.token);
 
     const ownership = {
       owner: github.context.repo.owner,
       repo: github.context.repo.repo,
-    }
+    };
+    const sha = github.context.sha;
 
-    const info = { // TODO: from argument
-    }
-
-    const { data } = await octokit.checks.listForRef({
-      ...ownership,
-      ref: github.context.sha,
-    })
-
-    if (data.check_runs.length > 0) {
-      octokit.checks.update({
-        ...ownership,
-        check_run_id: data.check_runs[0].id,
-        ...info,
-      })
-    } else {
-      octokit.checks.create({
-        ...ownership,
-        head_sha: github.context.sha,
-        name: 'Check Run Test', // TODO: from argument
-        ...info,
-      })
+    switch (inputs.status) {
+      case 'in_progress':
+      case 'queued': {
+        const id = await createRun(octokit, sha, ownership, inputs, {completed: false});
+        core.saveState(stateID, id.toString());
+        break;
+      }
+      case 'completed': {
+        const id = core.getState(stateID);
+        if (id) {
+          updateRun(octokit, parseInt(id), ownership, inputs);
+        } else {
+          createRun(octokit, sha, ownership, inputs);
+        }
+        break;
+      }
     }
   } catch (error) {
-    core.setFailed(error.message)
+    core.setFailed(error.message);
   }
 }
 
-run()
+run();
diff --git a/src/namespaces/Inputs.ts b/src/namespaces/Inputs.ts
new file mode 100644
index 0000000..9bfcba3
--- /dev/null
+++ b/src/namespaces/Inputs.ts
@@ -0,0 +1,38 @@
+import {Octokit} from '@octokit/rest';
+
+export type Args = {
+  name: string;
+  token: string;
+  conclusion: Conclusion;
+  status: Status;
+  output?: Output;
+  annotations?: Annotations;
+  images?: Images;
+  actions?: Actions;
+};
+
+export type Annotations = Octokit.ChecksCreateParamsOutputAnnotations[];
+
+export type Images = Octokit.ChecksCreateParamsOutputImages[];
+
+export type Actions = Octokit.ChecksCreateParamsActions[];
+
+export type Output = {
+  summary: string;
+  text_description?: string;
+};
+
+export enum Conclusion {
+  Success = 'success',
+  Failure = 'failure',
+  Neutral = 'neutral',
+  Cancelled = 'cancelled',
+  TimedOut = 'timed_out',
+  ActionRequired = 'action_required',
+}
+
+export enum Status {
+  Queued = 'queued',
+  InProgress = 'in_progress',
+  Completed = 'completed',
+}