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

[FLORA-412] GitHub repo funding information #428

Draft
wants to merge 5 commits into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# CHANGELOG

## 1.0.13 -- XXXX-XX-XX
* Integrating Funding information from GitHub source repository ([#412](https://github.com/flora-pm/flora-server/issues/412))
* Fixed text color for header and button in login page ([#418](https://github.com/flora-pm/flora-server/pull/418))
* Exclude deprecated releases from latest versions and search ([#373](https://github.com/flora-pm/flora-server/pull/373))
* Add namespace browsing ([#375](https://github.com/flora-pm/flora-server/pull/375))
Expand Down
3 changes: 3 additions & 0 deletions flora.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,8 @@ library flora-jobs
FloraJobs.Render
FloraJobs.Runner
FloraJobs.Scheduler
FloraJobs.ThirdParties.GitHub.API
FloraJobs.ThirdParties.GitHub.Client
FloraJobs.ThirdParties.Hackage.API
FloraJobs.ThirdParties.Hackage.Client
FloraJobs.Types
Expand All @@ -342,6 +344,7 @@ library flora-jobs
, containers
, effectful-core
, flora
, github
, http-client
, http-media
, http-types
Expand Down
2 changes: 1 addition & 1 deletion scripts/.zshrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env zsh

set -euo pipefail
set -o pipefail

export SHELL="zsh"
export ZSH="$HOME/.oh-my-zsh"
Expand Down
2 changes: 2 additions & 0 deletions src/core/Flora/Environment.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ data FloraEnv = FloraEnv
, environment :: DeploymentEnv
, config :: FloraConfig
, assets :: Assets
, githubToken :: Maybe ByteString
}
deriving stock (Generic)

Expand Down Expand Up @@ -82,6 +83,7 @@ configToEnv floraConfig = do
, environment = floraConfig.environment
, assets = assets
, config = floraConfig
, githubToken = floraConfig.githubToken
}

testConfigToTestEnv :: TestConfig -> Eff '[IOE] TestEnv
Expand Down
8 changes: 8 additions & 0 deletions src/core/Flora/Environment/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import Env
, def
, help
, nonempty
, optional
, str
, switch
, var
Expand Down Expand Up @@ -108,6 +109,7 @@ data FloraConfig = FloraConfig
, httpPort :: Word16
, logging :: LoggingEnv
, environment :: DeploymentEnv
, githubToken :: Maybe ByteString
}
deriving stock (Show, Generic)

Expand Down Expand Up @@ -154,6 +156,11 @@ parseDeploymentEnv :: Parser Error DeploymentEnv
parseDeploymentEnv =
var deploymentEnv "FLORA_ENVIRONMENT" (help "Name of the current environment (production, development, test)")

parseGithubToken :: Parser Error (Maybe ByteString)
parseGithubToken =
optional $
var str "FLORA_GITHUB_TOKEN" (help "The GitHub Token for Flora")

parseConfig :: Parser Error FloraConfig
parseConfig =
FloraConfig
Expand All @@ -163,6 +170,7 @@ parseConfig =
<*> parsePort
<*> parseLoggingEnv
<*> parseDeploymentEnv
<*> parseGithubToken

parseTestConfig :: Parser Error TestConfig
parseTestConfig =
Expand Down
3 changes: 2 additions & 1 deletion src/core/Flora/Import/Package/Bulk.hs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ importFromStream appLogger user repository directImport stream = do
liftIO $
S.fold displayCount $
S.fromAsync $
S.mapM (processFile wq pool poolConfig) $
S.mapM
(processFile wq pool poolConfig)
stream
)
-- We want to refresh db and update latest timestamp even if we fell
Expand Down
1 change: 1 addition & 0 deletions src/core/Flora/Model/Job.hs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ data FloraOddJobs
| FetchPackageDeprecationList
| FetchReleaseDeprecationList PackageName (Vector ReleaseId)
| RefreshLatestVersions
| FetchFundingInformation Text Text
deriving stock (Generic)

-- TODO: Upstream these two ToJSON instances
Expand Down
14 changes: 13 additions & 1 deletion src/core/Flora/Model/Package/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Data.Aeson.Orphans ()
import Data.Aeson.TH
import Data.ByteString (ByteString)
import Data.ByteString.Lazy (fromStrict)
import Data.Map qualified as M
import Data.Maybe (fromJust, fromMaybe)
import Data.OpenApi (Schema (..), ToParamSchema (..), ToSchema (..), genericDeclareNamedSchema)
import Data.Text (Text, isPrefixOf, unpack)
Expand Down Expand Up @@ -188,6 +189,16 @@ instance FromField PackageStatus where
instance ToField PackageStatus where
toField = Escape . encodeUtf8 . display

newtype PackageFunding = PackageFunding {getPackageFunding :: M.Map Text Text}
deriving stock (Generic)
deriving
(Eq, Ord, Show, FromField, ToField, ToJSON, FromJSON, NFData)

-- parsePackageFunding :: ByteString -> Maybe PackageFunding

-- instance FromRow PackageStatus where
-- instance ToRow PackageStatus where

data Package = Package
{ packageId :: PackageId
, namespace :: Namespace
Expand All @@ -196,7 +207,8 @@ data Package = Package
, createdAt :: UTCTime
, updatedAt :: UTCTime
, status :: PackageStatus
, deprecationInfo :: Maybe PackageAlternatives
, -- , funding :: PackageFunding
deprecationInfo :: Maybe PackageAlternatives
}
deriving stock (Eq, Ord, Show, Generic)
deriving anyclass (FromRow, ToRow, NFData)
Expand Down
23 changes: 22 additions & 1 deletion src/jobs-worker/FloraJobs/Runner.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ import Control.Monad.IO.Class
import Data.Aeson (Result (..), fromJSON, toJSON)
import Data.Function
import Data.Set qualified as Set
import Data.Text (Text)
import Data.Text.Display
import Data.Text.Lazy.Encoding qualified as TL
import Data.Vector (Vector)
import Data.Vector qualified as Vector
import Effectful.PostgreSQL.Transact.Effect
import Effectful.Reader.Static qualified as Reader
import GitHub.Auth
import GitHub.Data.Content
import Log
import Network.HTTP.Types (gone410, notFound404, statusCode)
import OddJobs.Job (Job (..))
Expand All @@ -28,6 +32,7 @@ import Flora.Model.Release.Types
import Flora.Model.Release.Update qualified as Update
import FloraJobs.Render (renderMarkdown)
import FloraJobs.Scheduler
import FloraJobs.ThirdParties.GitHub.Client
import FloraJobs.ThirdParties.Hackage.API (HackagePreferredVersions (..), VersionedPackage (..))
import FloraJobs.ThirdParties.Hackage.Client qualified as Hackage
import FloraJobs.Types
Expand Down Expand Up @@ -68,6 +73,8 @@ runner job = localDomain "job-runner" $
fetchReleaseDeprecationList packageName releases
RefreshLatestVersions ->
Update.refreshLatestVersions
FetchFundingInformation owner repo ->
fetchFundingInformation owner repo

fetchChangeLog :: ChangelogJobPayload -> JobsRunner ()
fetchChangeLog payload@ChangelogJobPayload{packageName, packageVersion, releaseId} =
Expand Down Expand Up @@ -131,7 +138,7 @@ fetchUploadTime payload@UploadTimeJobPayload{packageName, packageVersion, releas
-- | This job fetches the deprecation list and inserts the appropriate metadata in the packages
fetchPackageDeprecationList :: JobsRunner ()
fetchPackageDeprecationList = do
result <- Hackage.request $ Hackage.getDeprecatedPackages
result <- Hackage.request Hackage.getDeprecatedPackages
case result of
Right deprecationList -> do
logInfo_ "Deprecation List retrieved"
Expand Down Expand Up @@ -189,3 +196,17 @@ assignNamespace =
then PackageAlternative (Namespace "haskell") p
else PackageAlternative (Namespace "hackage") p
)

fetchFundingInformation :: Text -> Text -> JobsRunner ()
fetchFundingInformation owner repo = do
JobsRunnerEnv{mGithubToken} <- Reader.ask @JobsRunnerEnv
case mGithubToken of
Nothing -> pure ()
Comment on lines +203 to +204
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In retrospect we should also perform such a check in fetchMetadataHandler so that we don't queue jobs for nothing in the absence of the GitHub Token

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will have a look at sorting this!

Just githubToken -> do
result <-
liftIO $
runRequest (OAuth githubToken) $
fetchFundingFile owner repo
case result of
Left e -> error (show e)
Right (ContentFile content) -> liftIO $ print content.contentFileContent
13 changes: 13 additions & 0 deletions src/jobs-worker/FloraJobs/Scheduler.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module FloraJobs.Scheduler
, schedulePackageDeprecationListJob
, scheduleReleaseDeprecationListJob
, scheduleRefreshLatestVersions
, scheduleFetchFundingInformation
, checkIfIndexImportJobIsNotRunning
, jobTableName
-- prefer using smart constructors.
Expand All @@ -19,6 +20,7 @@ module FloraJobs.Scheduler
where

import Data.Pool
import Data.Text (Text)
import Data.Time qualified as Time
import Data.Vector (Vector)
import Database.PostgreSQL.Entity.DBT
Expand Down Expand Up @@ -116,6 +118,17 @@ scheduleRefreshLatestVersions pool =
RefreshLatestVersions
)

scheduleFetchFundingInformation :: Pool PG.Connection -> Text -> Text -> IO Job
scheduleFetchFundingInformation pool owner repo =
withResource
pool
( \conn ->
createJob
conn
jobTableName
(FetchFundingInformation owner repo)
)

checkIfIndexImportJobIsNotRunning :: JobsRunner Bool
checkIfIndexImportJobIsNotRunning = do
Log.logInfo_ "Checking if the index import job is not running…"
Expand Down
1 change: 1 addition & 0 deletions src/jobs-worker/FloraJobs/ThirdParties/GitHub/API.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module FloraJobs.ThirdParties.GitHub.API where
16 changes: 16 additions & 0 deletions src/jobs-worker/FloraJobs/ThirdParties/GitHub/Client.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module FloraJobs.ThirdParties.GitHub.Client where

import Data.Proxy
import Data.Text
import GitHub

runRequest :: Auth -> Request k Content -> IO (Either Error Content)
runRequest auth request =
github auth request

fetchFundingFile :: Text -> Text -> Request k Content
fetchFundingFile textOwner textRepo =
let owner = mkName (Proxy :: Proxy Owner) textOwner
repo = mkName (Proxy :: Proxy Repo) textRepo
filePath = ".github/FUNDING.yml"
in contentsForR owner repo filePath Nothing
2 changes: 2 additions & 0 deletions src/jobs-worker/FloraJobs/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module FloraJobs.Types where
import Commonmark qualified
import Control.Exception (Exception)
import Data.Aeson
import Data.ByteString (ByteString)
import Data.Pool hiding (PoolConfig)
import Data.Text qualified as Text
import Data.Text.Encoding.Error (UnicodeException)
Expand Down Expand Up @@ -73,6 +74,7 @@ jobTableName = "oddjobs"

data JobsRunnerEnv = JobsRunnerEnv
{ httpManager :: Manager
, mGithubToken :: Maybe ByteString
}
deriving stock (Generic)

Expand Down
2 changes: 1 addition & 1 deletion src/web/FloraWeb/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ logException env logger exception =
runServer :: (Concurrent :> es, IOE :> es) => Logger -> FloraEnv -> Eff es ()
runServer appLogger floraEnv = do
httpManager <- liftIO $ HTTP.newManager tlsManagerSettings
let runnerEnv = JobsRunnerEnv httpManager
let runnerEnv = JobsRunnerEnv httpManager floraEnv.githubToken
let oddjobsUiCfg = makeUIConfig (floraEnv.config) appLogger (floraEnv.jobsPool)
oddJobsCfg =
makeConfig
Expand Down