@@ -11,7 +11,7 @@ import qualified Data.Text as T
11
11
import qualified Data.Text.Encoding as TE
12
12
import qualified Network.HTTP.Client as HTTP
13
13
import Network.HTTP.Client.TLS (tlsManagerSettings )
14
- import System.Environment (getEnv , lookupEnv )
14
+ import System.Environment (getEnv , lookupEnv , setEnv )
15
15
import Network.HTTP.Types.Status (Status (.. ))
16
16
import Data.Aeson.Decoding (eitherDecode )
17
17
import qualified Data.Text as Text
@@ -55,40 +55,49 @@ initClient appState = do
55
55
-- Prepare the HTTP manager
56
56
manager <- HTTP. newManager tlsManagerSettings
57
57
58
- let privateKeyBytes = encodeUtf8 $ Text. replace " |" " \n " $ toText privateKeyStr
59
- let privateKey = fromMaybe (error " Invalid github key" ) $ readRsaSecret privateKeyBytes
58
+ let createToken = do
59
+ let privateKeyBytes = encodeUtf8 $ Text. replace " |" " \n " $ toText privateKeyStr
60
+ let privateKey = fromMaybe (error " Invalid github key" ) $ readRsaSecret privateKeyBytes
60
61
61
- -- Create the JWT token
62
- now <- getPOSIXTime
63
- let claims = mempty { iss = stringOrURI $ T. pack appId
64
- , iat = numericDate now
65
- , exp = numericDate (now + 5 * 60 )
66
- }
67
- let jwt = encodeSigned (EncodeRSAPrivateKey privateKey) (mempty { alg = Just RS256 }) claims
62
+ -- Create the JWT token
63
+ now <- getPOSIXTime
64
+ let claims = mempty { iss = stringOrURI $ T. pack appId
65
+ , iat = numericDate now
66
+ , exp = numericDate (now + 5 * 60 )
67
+ }
68
+ let jwt = encodeSigned (EncodeRSAPrivateKey privateKey) (mempty { alg = Just RS256 }) claims
68
69
69
- -- Get the installation access token
70
- let installUrl = apiUrl <> " /app/installations/" ++ installationId ++ " /access_tokens"
71
- initRequest <- HTTP. parseRequest installUrl
72
- let request = initRequest
73
- { HTTP. method = " POST"
74
- , HTTP. requestHeaders =
75
- [ (" Authorization" , " Bearer " <> TE. encodeUtf8 jwt)
76
- , (" Accept" , " application/vnd.github.v3+json" )
77
- , (" User-Agent" , " restaumatic-bot" )
78
- ]
79
- }
80
- response <- HTTP. httpLbs request manager
81
- let mTokenResponse = eitherDecode @ InstallationTokenResponse (HTTP. responseBody response)
82
- accessToken <- case mTokenResponse of
83
- Left err -> do
84
- logError appState $ " CommitStatus: Failed to parse installation token response: " <> show err
85
- logError appState $ " CommitStatus: Response: " <> decodeUtf8 response. responseBody
70
+ -- Get the installation access token
71
+ let installUrl = apiUrl <> " /app/installations/" ++ installationId ++ " /access_tokens"
72
+ initRequest <- HTTP. parseRequest installUrl
73
+ let request = initRequest
74
+ { HTTP. method = " POST"
75
+ , HTTP. requestHeaders =
76
+ [ (" Authorization" , " Bearer " <> TE. encodeUtf8 jwt)
77
+ , (" Accept" , " application/vnd.github.v3+json" )
78
+ , (" User-Agent" , " restaumatic-bot" )
79
+ ]
80
+ }
81
+ response <- HTTP. httpLbs request manager
82
+ let mTokenResponse = eitherDecode @ InstallationTokenResponse (HTTP. responseBody response)
83
+ case mTokenResponse of
84
+ Left err -> do
85
+ logError appState $ " CommitStatus: Failed to parse installation token response: " <> show err
86
+ logError appState $ " CommitStatus: Response: " <> decodeUtf8 response. responseBody
86
87
87
- -- FIXME: handle the error better
88
- exitFailure
89
- Right tokenResponse ->
90
- pure tokenResponse. token
88
+ -- FIXME: handle the error better
89
+ exitFailure
90
+ Right tokenResponse ->
91
+ pure tokenResponse. token
91
92
93
+ -- Try to read token from environment variable
94
+ -- Otherwise generate a new one, and set env for future uses (also in child processes)
95
+ accessToken <- lookupEnv " _taskrunner_github_access_token" >>= \ case
96
+ Just token -> pure $ T. pack token
97
+ Nothing -> do
98
+ token <- createToken
99
+ setEnv " _taskrunner_github_access_token" $ T. unpack token
100
+ pure token
92
101
93
102
pure $ GithubClient { apiUrl = T. pack apiUrl
94
103
, appId = T. pack appId
0 commit comments