Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

First implementaiton of github-app-token package #1

Merged
merged 15 commits into from
Sep 12, 2024
51 changes: 51 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: CI

on:
pull_request:
push:
branches: main

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- id: generate
uses: freckle/stack-action/generate-matrix@v5
outputs:
stack-yamls: ${{ steps.generate.outputs.stack-yamls }}

test:
runs-on: ubuntu-latest
needs: generate

strategy:
matrix:
stack-yaml: ${{ fromJSON(needs.generate.outputs.stack-yamls) }}
fail-fast: false

steps:
- uses: actions/checkout@v4
- run: |
cat > github-app-token/key.pem <<'EOM'
${{ secrets.FRECKLE_AUTOMATION_PRIVATE_KEY }}
EOM

- uses: freckle/stack-action@v5
env:
STACK_YAML: ${{ matrix.stack-yaml }}
GITHUB_APP_ID: ${{ vars.FRECKLE_AUTOMATION_APP_ID }}
GITHUB_INSTALLATION_ID: ${{ vars.FRECKLE_AUTOMATION_INSTALLATION_ID }}

lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: haskell-actions/hlint-setup@v2
- uses: haskell-actions/hlint-run@v2
with:
fail-on: warning
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.env*
!.env.example

.stack-work

key.pem
4 changes: 4 additions & 0 deletions .restyled.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
restylers:
- "fourmolu"
- "!stylish-haskell"
- "*"
15 changes: 15 additions & 0 deletions fourmolu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
indentation: 2
column-limit: 80
function-arrows: leading
comma-style: leading # default
import-export-style: leading
indent-wheres: false # default
record-brace-space: true
newlines-between-decls: 1 # default
haddock-style: single-line
let-style: mixed
in-style: left-align
single-constraint-parens: never
unicode: never # default
respectful: true # default
fixities: [] # default
6 changes: 6 additions & 0 deletions github-app-token/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# shellcheck disable=SC2034
# Fill out and place this file at .env to run the README.lhs test
GITHUB_APP_ID=
GITHUB_INSTALLATION_ID=

# Additionally, copy the private key to key.pem
1 change: 1 addition & 0 deletions github-app-token/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# TODO
65 changes: 65 additions & 0 deletions github-app-token/README.lhs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# GitHub App Token

[Generate an installation access token for a GitHub App][docs]

[docs]: https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation

## Usage

<!--
```haskell
{-# LANGUAGE TemplateHaskell #-}

module Main (module Main) where

import Configuration.Dotenv qualified as Dotenv
import Control.Monad (when)
import System.Directory (doesFileExist)
import Text.Markdown.Unlit ()
```
-->

```haskell
import Prelude

import Control.Lens ((^?))
import Data.Aeson
import Data.Aeson.Lens
import Data.Text.Encoding (encodeUtf8)
import GitHub.App.Token
import Network.HTTP.Simple
import Network.HTTP.Types.Header (hUserAgent, hAuthorization)
import System.Environment
import Path (mkRelFile)

example :: IO ()
example = do
-- NB: see the separate github-app-token-cli for nicer ways to load these
-- secrets within optparse-applicative and/or envparse.
appId <- AppId . read <$> getEnv "GITHUB_APP_ID"
privateKey <- readPrivateKey $(mkRelFile "key.pem")
installationId <- InstallationId . read <$> getEnv "GITHUB_INSTALLATION_ID"

-- Generate token
token <- generateInstallationToken AppCredentials {appId, privateKey} installationId

-- Use token
req <- parseRequest "https://api.github.com/repos/freckle/github-app-token"
resp <- httpJSON @_ @Value
$ addRequestHeader hUserAgent "github-app-token/example"
$ addRequestHeader hAuthorization ("Bearer " <> encodeUtf8 token.token)
$ req

print $ getResponseBody resp ^? key "description" . _String
-- Just "Generate an installation token for a GitHub App"
```

<!--
```haskell
main :: IO ()
main = do
isLocal <- doesFileExist ".env"
when isLocal $ Dotenv.loadFile Dotenv.defaultConfig
example
```
-->
1 change: 1 addition & 0 deletions github-app-token/README.md
100 changes: 100 additions & 0 deletions github-app-token/github-app-token.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
cabal-version: 1.18

-- This file has been generated from package.yaml by hpack version 0.37.0.
--
-- see: https://github.com/sol/hpack

name: github-app-token
version: 0.0.0.0
synopsis: Generate an installation access token for a GitHub App
description: Please see README.md
category: HTTP
homepage: https://github.com/freckle/github-app-token#readme
bug-reports: https://github.com/freckle/github-app-token/issues
maintainer: Freckle Education
build-type: Simple
extra-doc-files:
README.md
CHANGELOG.md

source-repository head
type: git
location: https://github.com/freckle/github-app-token

library
exposed-modules:
GitHub.App.Token
GitHub.App.Token.AppCredentials
GitHub.App.Token.Generate
GitHub.App.Token.JWT
GitHub.App.Token.Prelude
other-modules:
Paths_github_app_token
hs-source-dirs:
src
default-extensions:
DataKinds
DeriveAnyClass
DerivingVia
DerivingStrategies
DuplicateRecordFields
GADTs
LambdaCase
NoImplicitPrelude
NoMonomorphismRestriction
OverloadedRecordDot
OverloadedStrings
RecordWildCards
TypeFamilies
ghc-options: -fignore-optim-changes -fwrite-ide-info -Weverything -Wno-all-missed-specialisations -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missing-kind-signatures -Wno-missing-local-signatures -Wno-missing-safe-haskell-mode -Wno-monomorphism-restriction -Wno-prepositive-qualified-module -Wno-safe -Wno-unsafe
build-depends:
aeson
, base <5
, bytestring
, http-conduit
, http-types
, jwt
, path
, text
, time
, unliftio
default-language: GHC2021
if impl(ghc >= 9.8)
ghc-options: -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures

test-suite readme
type: exitcode-stdio-1.0
main-is: README.lhs
other-modules:
Paths_github_app_token
default-extensions:
DataKinds
DeriveAnyClass
DerivingVia
DerivingStrategies
DuplicateRecordFields
GADTs
LambdaCase
NoImplicitPrelude
NoMonomorphismRestriction
OverloadedRecordDot
OverloadedStrings
RecordWildCards
TypeFamilies
ghc-options: -fignore-optim-changes -fwrite-ide-info -Weverything -Wno-all-missed-specialisations -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missing-kind-signatures -Wno-missing-local-signatures -Wno-missing-safe-haskell-mode -Wno-monomorphism-restriction -Wno-prepositive-qualified-module -Wno-safe -Wno-unsafe -pgmL markdown-unlit
build-depends:
aeson
, base <5
, directory
, dotenv
, github-app-token
, http-conduit
, http-types
, lens
, lens-aeson
, markdown-unlit
, path
, text
default-language: GHC2021
if impl(ghc >= 9.8)
ghc-options: -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures
88 changes: 88 additions & 0 deletions github-app-token/package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: github-app-token
version: 0.0.0.0
maintainer: Freckle Education
category: HTTP
github: freckle/github-app-token
synopsis: Generate an installation access token for a GitHub App
description: Please see README.md

extra-doc-files:
- README.md
- CHANGELOG.md

language: GHC2021

ghc-options:
- -fignore-optim-changes
- -fwrite-ide-info
- -Weverything
- -Wno-all-missed-specialisations
- -Wno-missing-exported-signatures # re-enables missing-signatures
- -Wno-missing-import-lists
- -Wno-missing-kind-signatures
- -Wno-missing-local-signatures
- -Wno-missing-safe-haskell-mode
- -Wno-monomorphism-restriction
- -Wno-prepositive-qualified-module
- -Wno-safe
- -Wno-unsafe

when:
- condition: "impl(ghc >= 9.8)"
ghc-options:
- -Wno-missing-role-annotations
- -Wno-missing-poly-kind-signatures

dependencies:
- base < 5

default-extensions:
- DataKinds
- DeriveAnyClass
- DerivingVia
- DerivingStrategies
- DuplicateRecordFields
- GADTs
- LambdaCase
- NoImplicitPrelude
- NoMonomorphismRestriction
- OverloadedRecordDot
- OverloadedStrings
- RecordWildCards
- TypeFamilies

library:
source-dirs: src
dependencies:
- aeson
- bytestring
- http-conduit
- jwt
- text
- time
- http-types
- path
- unliftio

tests:
# spec:
# main: Main.hs
# source-dirs: tests
# ghc-options: -threaded -rtsopts "-with-rtsopts=-N"
# dependencies:
# - github-app-token
readme:
main: README.lhs
ghc-options: -pgmL markdown-unlit
dependencies:
- aeson
- directory
- dotenv
- github-app-token
- http-conduit
- http-types
- lens
- lens-aeson
- markdown-unlit
- path
- text
13 changes: 13 additions & 0 deletions github-app-token/src/GitHub/App/Token.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module GitHub.App.Token
( generateInstallationToken
, AppCredentials (..)
, AppId (..)
, PrivateKey (..)
, readPrivateKey
, InstallationId (..)
, AccessToken (..)
) where

import GitHub.App.Token.AppCredentials
import GitHub.App.Token.Generate
import GitHub.App.Token.JWT
17 changes: 17 additions & 0 deletions github-app-token/src/GitHub/App/Token/AppCredentials.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module GitHub.App.Token.AppCredentials
( AppCredentials (..)
, AppId (..)
, PrivateKey (..)
) where

import GitHub.App.Token.JWT (PrivateKey (..))
import GitHub.App.Token.Prelude

data AppCredentials = AppCredentials
{ appId :: AppId
, privateKey :: PrivateKey
}

newtype AppId = AppId
{ unwrap :: Int
}
Loading