mirror of
https://github.com/ryantm/nixpkgs-update.git
synced 2024-09-11 13:57:20 +03:00
Compare commits
9 Commits
936918ca61
...
df23e62c33
Author | SHA1 | Date | |
---|---|---|---|
|
df23e62c33 | ||
|
fc6a441992 | ||
|
5b65371222 | ||
|
256708538c | ||
|
6e45a0911d | ||
|
71ab24a2eb | ||
|
0572aa48da | ||
|
9c6d0ff795 | ||
|
a57bd0d25e |
@ -116,7 +116,8 @@ commandParser =
|
||||
|
||||
checkVulnerable :: O.Parser Command
|
||||
checkVulnerable =
|
||||
CheckVulnerable <$> O.strArgument (O.metavar "PRODUCT_ID")
|
||||
CheckVulnerable
|
||||
<$> O.strArgument (O.metavar "PRODUCT_ID")
|
||||
<*> O.strArgument (O.metavar "OLD_VERSION")
|
||||
<*> O.strArgument (O.metavar "NEW_VERSION")
|
||||
|
||||
|
@ -36,7 +36,7 @@ Updates can be disabled by adding a comment to the package:
|
||||
|
||||
We maintain a [Skiplist](https://github.com/ryantm/nixpkgs-update/blob/main/src/Skiplist.hs) of different things not to update. It is possible your package is triggering one of the skip criteria.
|
||||
|
||||
Python updates are skipped if they cause more than 25 rebuilds.
|
||||
Python updates are skipped if they cause more than 100 rebuilds.
|
||||
|
||||
### Existing Open or Draft PR
|
||||
|
||||
|
40
flake.lock
40
flake.lock
@ -54,7 +54,45 @@
|
||||
"root": {
|
||||
"inputs": {
|
||||
"mmdoc": "mmdoc",
|
||||
"nixpkgs": "nixpkgs"
|
||||
"nixpkgs": "nixpkgs",
|
||||
"runtimeDeps": "runtimeDeps",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
}
|
||||
},
|
||||
"runtimeDeps": {
|
||||
"locked": {
|
||||
"lastModified": 1714247354,
|
||||
"narHash": "sha256-6dFKqP/aCKIdpOgqgIQUrRT0NOfVc14ftNcdELa4Pu4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "c8d7c8a78fb516c0842cc65346506a565c88014d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable-small",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1711963903,
|
||||
"narHash": "sha256-N3QDhoaX+paWXHbEXZapqd1r95mdshxToGowtjtYkGI=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "49dc4a92b02b8e68798abd99184f228243b6e3ac",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
21
flake.nix
21
flake.nix
@ -4,17 +4,34 @@
|
||||
inputs.mmdoc.url = "github:ryantm/mmdoc";
|
||||
inputs.mmdoc.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
inputs.treefmt-nix.url = "github:numtide/treefmt-nix";
|
||||
inputs.treefmt-nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
inputs.runtimeDeps.url = "github:NixOS/nixpkgs/nixos-unstable-small";
|
||||
|
||||
nixConfig.extra-substituters = "https://nix-community.cachix.org";
|
||||
nixConfig.extra-trusted-public-keys = "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=";
|
||||
|
||||
outputs = { self, nixpkgs, mmdoc } @ args:
|
||||
outputs = { self, nixpkgs, mmdoc, treefmt-nix, runtimeDeps } @ args:
|
||||
let
|
||||
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
|
||||
eachSystem = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
|
||||
treefmtEval = eachSystem (pkgs: treefmt-nix.lib.evalModule pkgs {
|
||||
projectRootFile = ".git/config";
|
||||
programs.ormolu.enable = true;
|
||||
});
|
||||
in
|
||||
{
|
||||
checks.x86_64-linux =
|
||||
let
|
||||
packages = nixpkgs.lib.mapAttrs' (n: nixpkgs.lib.nameValuePair "package-${n}") self.packages.x86_64-linux;
|
||||
devShells = nixpkgs.lib.mapAttrs' (n: nixpkgs.lib.nameValuePair "devShell-${n}") self.devShells.x86_64-linux;
|
||||
in
|
||||
packages // devShells;
|
||||
packages // devShells // {
|
||||
treefmt = treefmtEval.x86_64-linux.config.build.check self;
|
||||
};
|
||||
|
||||
formatter = eachSystem (pkgs: treefmtEval.${pkgs.system}.config.build.wrapper);
|
||||
|
||||
packages.x86_64-linux = import ./pkgs/default.nix (args // { system = "x86_64-linux"; });
|
||||
devShells.x86_64-linux.default = self.packages."x86_64-linux".devShell;
|
||||
|
@ -1,5 +1,6 @@
|
||||
{ nixpkgs
|
||||
, mmdoc
|
||||
, runtimeDeps
|
||||
, system
|
||||
, self
|
||||
, ...
|
||||
@ -7,9 +8,11 @@
|
||||
|
||||
let
|
||||
|
||||
runtimePkgs = import runtimeDeps { inherit system; };
|
||||
|
||||
pkgs = import nixpkgs { inherit system; config = { allowBroken = true; }; };
|
||||
|
||||
drvAttrs = attrs: with pkgs; {
|
||||
drvAttrs = attrs: with runtimePkgs; {
|
||||
NIX = nix;
|
||||
GIT = git;
|
||||
JQ = jq;
|
||||
|
@ -16,6 +16,7 @@ where
|
||||
|
||||
import Data.Aeson
|
||||
( FromJSON,
|
||||
Key,
|
||||
Object,
|
||||
eitherDecode,
|
||||
parseJSON,
|
||||
@ -23,7 +24,6 @@ import Data.Aeson
|
||||
(.!=),
|
||||
(.:),
|
||||
(.:!),
|
||||
Key,
|
||||
)
|
||||
import Data.Aeson.Types (Parser, prependFailure)
|
||||
import qualified Data.ByteString.Lazy.Char8 as BSL
|
||||
|
30
src/Check.hs
30
src/Check.hs
@ -8,7 +8,7 @@ module Check
|
||||
( result,
|
||||
-- exposed for testing:
|
||||
hasVersion,
|
||||
versionWithoutPath
|
||||
versionWithoutPath,
|
||||
)
|
||||
where
|
||||
|
||||
@ -50,10 +50,10 @@ isNonWordCharacter c = not (isWordCharacter c)
|
||||
-- | Construct regex: /.*\b${version}\b.*/s
|
||||
versionRegex :: Text -> RE' ()
|
||||
versionRegex version =
|
||||
(\_ -> ()) <$> (
|
||||
(((many RE.anySym) <* (RE.psym isNonWordCharacter)) <|> (RE.pure ""))
|
||||
*> (RE.string version) <*
|
||||
((RE.pure "") <|> ((RE.psym isNonWordCharacter) *> (many RE.anySym)))
|
||||
(\_ -> ())
|
||||
<$> ( (((many RE.anySym) <* (RE.psym isNonWordCharacter)) <|> (RE.pure ""))
|
||||
*> (RE.string version)
|
||||
<* ((RE.pure "") <|> ((RE.psym isNonWordCharacter) *> (many RE.anySym)))
|
||||
)
|
||||
|
||||
hasVersion :: Text -> Text -> Bool
|
||||
@ -63,10 +63,9 @@ hasVersion contents expectedVersion =
|
||||
checkTestsBuild :: Text -> IO Bool
|
||||
checkTestsBuild attrPath = do
|
||||
let timeout = "10m"
|
||||
let
|
||||
args =
|
||||
[ T.unpack timeout, "nix-build" ] ++
|
||||
nixBuildOptions
|
||||
let args =
|
||||
[T.unpack timeout, "nix-build"]
|
||||
++ nixBuildOptions
|
||||
++ [ "-E",
|
||||
"{ config }: (import ./. { inherit config; })."
|
||||
++ (T.unpack attrPath)
|
||||
@ -99,8 +98,8 @@ versionWithoutPath resultPath expectedVersion =
|
||||
-- This can be done with negative lookbehind e.g
|
||||
-- /^(?<!${storePathWithoutVersion})${version}/
|
||||
-- Note we also escape the version with \Q/\E for grep -P
|
||||
let storePath = fromMaybe (T.pack resultPath) $ T.stripPrefix "/nix/store/" (T.pack resultPath) in
|
||||
case T.breakOn expectedVersion storePath of
|
||||
let storePath = fromMaybe (T.pack resultPath) $ T.stripPrefix "/nix/store/" (T.pack resultPath)
|
||||
in case T.breakOn expectedVersion storePath of
|
||||
(_, "") ->
|
||||
-- no version in prefix, just match version
|
||||
"\\Q"
|
||||
@ -140,7 +139,8 @@ foundVersionInFileNames expectedVersion resultPath =
|
||||
( do
|
||||
(_, contents) <-
|
||||
shell ("find " <> resultPath) & ourReadProcessInterleaved
|
||||
(contents =~ versionRegex expectedVersion) & hoistMaybe
|
||||
(contents =~ versionRegex expectedVersion)
|
||||
& hoistMaybe
|
||||
& noteT (T.pack "Expected version not found")
|
||||
return $
|
||||
"- found "
|
||||
@ -157,7 +157,8 @@ treeGist resultPath =
|
||||
( do
|
||||
contents <- procTree [resultPath] & ourReadProcessInterleavedBS_
|
||||
g <-
|
||||
shell gistBin & setStdin (byteStringInput contents)
|
||||
shell gistBin
|
||||
& setStdin (byteStringInput contents)
|
||||
& ourReadProcessInterleaved_
|
||||
return $ "- directory tree listing: " <> g <> "\n"
|
||||
)
|
||||
@ -169,7 +170,8 @@ duGist resultPath =
|
||||
( do
|
||||
contents <- proc "du" [resultPath] & ourReadProcessInterleavedBS_
|
||||
g <-
|
||||
shell gistBin & setStdin (byteStringInput contents)
|
||||
shell gistBin
|
||||
& setStdin (byteStringInput contents)
|
||||
& ourReadProcessInterleaved_
|
||||
return $ "- du listing: " <> g <> "\n"
|
||||
)
|
||||
|
32
src/GH.hs
32
src/GH.hs
@ -23,7 +23,7 @@ import Data.Aeson (FromJSON)
|
||||
import Data.Bitraversable (bitraverse)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as T
|
||||
import Data.Time.Clock (getCurrentTime, addUTCTime)
|
||||
import Data.Time.Clock (addUTCTime, getCurrentTime)
|
||||
import qualified Data.Vector as V
|
||||
import qualified Git
|
||||
import qualified GitHub as GH
|
||||
@ -54,12 +54,14 @@ pr env title body prHead base = do
|
||||
tryPR `catchE` \case
|
||||
-- If creating the PR returns a 422, most likely cause is that the
|
||||
-- branch was deleted, so push it again and retry once.
|
||||
GH.HTTPError (HttpExceptionRequest _ (StatusCodeException r _)) | statusCode (responseStatus r) == 422 ->
|
||||
GH.HTTPError (HttpExceptionRequest _ (StatusCodeException r _))
|
||||
| statusCode (responseStatus r) == 422 ->
|
||||
Git.push env >> withExceptT (T.pack . show) tryPR
|
||||
e ->
|
||||
throwE . T.pack . show $ e
|
||||
where
|
||||
tryPR = ExceptT $
|
||||
tryPR =
|
||||
ExceptT $
|
||||
fmap ((False,) . GH.getUrl . GH.pullRequestUrl)
|
||||
<$> ( liftIO $
|
||||
( GH.github
|
||||
@ -78,23 +80,24 @@ prUpdate env title body prHead base = do
|
||||
runRequest = ExceptT . fmap (first (T.pack . show)) . liftIO . GH.github (authFrom env)
|
||||
let inNixpkgs f = f (N "nixos") (N "nixpkgs")
|
||||
|
||||
prs <- runRequest $
|
||||
prs <-
|
||||
runRequest $
|
||||
inNixpkgs GH.pullRequestsForR (GH.optionsHead prHead) GH.FetchAll
|
||||
|
||||
case V.toList prs of
|
||||
[] -> pr env title body prHead base
|
||||
|
||||
(_ : _ : _) -> throwE $ "Too many open PRs from " <> prHead
|
||||
|
||||
[thePR] -> do
|
||||
let withExistingPR :: (GH.Name GH.Owner -> GH.Name GH.Repo -> GH.IssueNumber -> a) -> a
|
||||
withExistingPR f = inNixpkgs f (GH.simplePullRequestNumber thePR)
|
||||
|
||||
_ <- runRequest $
|
||||
_ <-
|
||||
runRequest $
|
||||
withExistingPR GH.updatePullRequestR $
|
||||
GH.EditPullRequest (Just title) Nothing Nothing Nothing Nothing
|
||||
|
||||
_ <- runRequest $
|
||||
_ <-
|
||||
runRequest $
|
||||
withExistingPR GH.createCommentR body
|
||||
|
||||
return (True, GH.getUrl $ GH.simplePullRequestUrl thePR)
|
||||
@ -129,12 +132,18 @@ parseURLMaybe url =
|
||||
extension = RE.string ".zip" <|> RE.string ".tar.gz"
|
||||
toParts n o = URLParts (N n) (N o)
|
||||
regex =
|
||||
( toParts <$> (domain *> pathSegment) <* slash <*> pathSegment
|
||||
( toParts
|
||||
<$> (domain *> pathSegment)
|
||||
<* slash
|
||||
<*> pathSegment
|
||||
<*> (RE.string "/releases/download/" *> pathSegment)
|
||||
<* slash
|
||||
<* pathSegment
|
||||
)
|
||||
<|> ( toParts <$> (domain *> pathSegment) <* slash <*> pathSegment
|
||||
<|> ( toParts
|
||||
<$> (domain *> pathSegment)
|
||||
<* slash
|
||||
<*> pathSegment
|
||||
<*> (RE.string "/archive/" *> pathSegment)
|
||||
<* extension
|
||||
)
|
||||
@ -187,7 +196,8 @@ commitIsOldEnoughToDelete auth ghUser sha = do
|
||||
|
||||
refShouldBeDeleted :: GH.Auth -> GH.Name GH.Owner -> (Text, GH.Name GH.GitCommit) -> IO Bool
|
||||
refShouldBeDeleted auth ghUser (ref, sha) =
|
||||
liftA2 (&&)
|
||||
liftA2
|
||||
(&&)
|
||||
(either (const False) not <$> openPRWithAutoUpdateRefFrom auth ghUser ref)
|
||||
(commitIsOldEnoughToDelete auth ghUser sha)
|
||||
|
||||
|
12
src/Git.hs
12
src/Git.hs
@ -18,7 +18,7 @@ module Git
|
||||
setupNixpkgs,
|
||||
Git.show,
|
||||
worktreeAdd,
|
||||
worktreeRemove
|
||||
worktreeRemove,
|
||||
)
|
||||
where
|
||||
|
||||
@ -33,7 +33,7 @@ import Data.Time.Clock (addUTCTime, getCurrentTime)
|
||||
import qualified Data.Vector as V
|
||||
import Language.Haskell.TH.Env (envQ)
|
||||
import OurPrelude hiding (throw)
|
||||
import System.Directory (doesDirectoryExist, doesFileExist, getModificationTime, getCurrentDirectory, setCurrentDirectory)
|
||||
import System.Directory (doesDirectoryExist, doesFileExist, getCurrentDirectory, getModificationTime, setCurrentDirectory)
|
||||
import System.Environment.XDG.BaseDir (getUserCacheDir)
|
||||
import System.Exit ()
|
||||
import System.IO.Error (tryIOError)
|
||||
@ -98,7 +98,8 @@ diff :: MonadIO m => Text -> ExceptT Text m Text
|
||||
diff branch = readProcessInterleavedNoIndexIssue_ $ procGit ["diff", T.unpack branch]
|
||||
|
||||
diffFileNames :: MonadIO m => Text -> ExceptT Text m [Text]
|
||||
diffFileNames branch = readProcessInterleavedNoIndexIssue_ (procGit ["diff", T.unpack branch, "--name-only"])
|
||||
diffFileNames branch =
|
||||
readProcessInterleavedNoIndexIssue_ (procGit ["diff", T.unpack branch, "--name-only"])
|
||||
& fmapRT T.lines
|
||||
|
||||
staleFetchHead :: MonadIO m => m Bool
|
||||
@ -121,7 +122,8 @@ fetchIfStale = whenM staleFetchHead fetch
|
||||
fetch :: MonadIO m => ExceptT Text m ()
|
||||
fetch =
|
||||
runProcessNoIndexIssue_ $
|
||||
silently $ procGit ["fetch", "-q", "--prune", "--multiple", "upstream", "origin"]
|
||||
silently $
|
||||
procGit ["fetch", "-q", "--prune", "--multiple", "upstream", "origin"]
|
||||
|
||||
push :: MonadIO m => UpdateEnv -> ExceptT Text m ()
|
||||
push updateEnv =
|
||||
@ -210,7 +212,6 @@ deleteBranchesEverywhere branches = do
|
||||
Left error2 -> T.putStrLn $ tshow error2
|
||||
Right success2 -> T.putStrLn $ tshow success2
|
||||
|
||||
|
||||
runProcessNoIndexIssue_IO ::
|
||||
ProcessConfig () () () -> IO ()
|
||||
runProcessNoIndexIssue_IO config = go
|
||||
@ -253,7 +254,6 @@ readProcessInterleavedNoIndexIssue_ config = tryIOTextET go
|
||||
ExitSuccess -> return $ bytestringToText out
|
||||
ExitFailure _ -> throw $ ExitCodeException code config out out
|
||||
|
||||
|
||||
readProcessInterleavedNoIndexIssue_IO ::
|
||||
ProcessConfig () () () -> IO Text
|
||||
readProcessInterleavedNoIndexIssue_IO config = go
|
||||
|
@ -15,14 +15,18 @@ filter _ cpeMatch "socat" v
|
||||
| cpeUpdatePresentAndNotPartOfVersion cpeMatch v = False -- TODO consider if this rule should be applied to all packages
|
||||
filter _ cpeMatch "uzbl" v
|
||||
| isNothing (v =~ yearRegex)
|
||||
&& "2009.12.22" `anyVersionInfixOf` cpeMatchVersionMatcher cpeMatch =
|
||||
&& "2009.12.22"
|
||||
`anyVersionInfixOf` cpeMatchVersionMatcher cpeMatch =
|
||||
False
|
||||
| isNothing (v =~ yearRegex)
|
||||
&& "2010.04.03" `anyVersionInfixOf` cpeMatchVersionMatcher cpeMatch =
|
||||
&& "2010.04.03"
|
||||
`anyVersionInfixOf` cpeMatchVersionMatcher cpeMatch =
|
||||
False
|
||||
filter _ cpeMatch "go" v
|
||||
| "." `T.isInfixOf` v
|
||||
&& "-" `anyVersionInfixOf` cpeMatchVersionMatcher cpeMatch =
|
||||
| "."
|
||||
`T.isInfixOf` v
|
||||
&& "-"
|
||||
`anyVersionInfixOf` cpeMatchVersionMatcher cpeMatch =
|
||||
False
|
||||
filter _ cpeMatch "terraform" _
|
||||
| cpeTargetSoftware (cpeMatchCPE cpeMatch) == Just "aws" = False
|
||||
|
21
src/Nix.hs
21
src/Nix.hs
@ -40,8 +40,8 @@ import qualified Data.Text.Lazy.Encoding as TL
|
||||
import qualified Git
|
||||
import Language.Haskell.TH.Env (envQ)
|
||||
import OurPrelude
|
||||
import qualified System.Process.Typed as TP
|
||||
import System.Exit ()
|
||||
import qualified System.Process.Typed as TP
|
||||
import Utils (UpdateEnv (..), nixBuildOptions, nixCommonOptions, srcOrMain)
|
||||
import Prelude hiding (log)
|
||||
|
||||
@ -127,7 +127,8 @@ lookupAttrPath updateEnv =
|
||||
<> nixCommonOptions
|
||||
)
|
||||
& ourReadProcess_
|
||||
& fmapRT (fst >>> T.lines >>> head >>> T.words >>> head))
|
||||
& fmapRT (fst >>> T.lines >>> head >>> T.words >>> head)
|
||||
)
|
||||
<|>
|
||||
-- if that fails, check by attrpath
|
||||
(getAttrString "name" (packageName updateEnv))
|
||||
@ -178,7 +179,8 @@ getHomepage :: MonadIO m => Text -> ExceptT Text m Text
|
||||
getHomepage = nixEvalApplyRaw "p: p.meta.homepage or \"\""
|
||||
|
||||
getSrcUrl :: MonadIO m => Text -> ExceptT Text m Text
|
||||
getSrcUrl = srcOrMain
|
||||
getSrcUrl =
|
||||
srcOrMain
|
||||
(nixEvalApplyRaw "p: builtins.elemAt p.drvAttrs.urls 0")
|
||||
|
||||
buildCmd :: Text -> ProcessConfig () () ()
|
||||
@ -245,10 +247,9 @@ resultLink =
|
||||
|
||||
fakeHashMatching :: Text -> Text
|
||||
fakeHashMatching oldHash =
|
||||
if "sha512-" `T.isPrefixOf` oldHash then
|
||||
"sha512-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
|
||||
else
|
||||
"sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
|
||||
if "sha512-" `T.isPrefixOf` oldHash
|
||||
then "sha512-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
|
||||
else "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
|
||||
|
||||
-- fixed-output derivation produced path '/nix/store/fg2hz90z5bc773gpsx4gfxn3l6fl66nw-source' with sha256 hash '0q1lsgc1621czrg49nmabq6am9sgxa9syxrwzlksqqr4dyzw4nmf' instead of the expected hash '0bp22mzkjy48gncj5vm9b7whzrggcbs5pd4cnb6k8jpl9j02dhdv'
|
||||
getHashFromBuild :: MonadIO m => Text -> ExceptT Text m Text
|
||||
@ -289,13 +290,15 @@ hasPatchNamed attrPath name = do
|
||||
hasUpdateScript :: MonadIO m => Text -> ExceptT Text m Bool
|
||||
hasUpdateScript attrPath = do
|
||||
nixEvalApply
|
||||
"p: builtins.hasAttr \"updateScript\" p" attrPath
|
||||
"p: builtins.hasAttr \"updateScript\" p"
|
||||
attrPath
|
||||
& readNixBool
|
||||
|
||||
runUpdateScript :: MonadIO m => Text -> ExceptT Text m (ExitCode, Text)
|
||||
runUpdateScript attrPath = do
|
||||
let timeout = "10m" :: Text
|
||||
(exitCode, output) <- ourReadProcessInterleaved $
|
||||
(exitCode, output) <-
|
||||
ourReadProcessInterleaved $
|
||||
TP.setStdin (TP.byteStringInput "\n") $
|
||||
proc "timeout" [T.unpack timeout, "nix-shell", "maintainers/scripts/update.nix", "--argstr", "package", T.unpack attrPath]
|
||||
case exitCode of
|
||||
|
@ -33,7 +33,9 @@ run ::
|
||||
FilePath ->
|
||||
Text ->
|
||||
Sem r Text
|
||||
run cache commit = let timeout = "45m" :: Text in do
|
||||
run cache commit =
|
||||
let timeout = "120m" :: Text
|
||||
in do
|
||||
-- TODO: probably just skip running nixpkgs-review if the directory
|
||||
-- already exists
|
||||
void $
|
||||
@ -41,7 +43,7 @@ run cache commit = let timeout = "45m" :: Text in do
|
||||
proc "rm" ["-rf", revDir cache commit]
|
||||
(exitCode, _nixpkgsReviewOutput) <-
|
||||
ourReadProcessInterleavedSem $
|
||||
proc "timeout" [T.unpack timeout, (binPath <> "/nixpkgs-review"), "rev", T.unpack commit, "--no-shell"]
|
||||
proc "timeout" [T.unpack timeout, (binPath <> "/nixpkgs-review"), "rev", T.unpack commit, "--no-shell", "--extra-nixpkgs-config", "{ allowInsecurePredicate = x: true; }"]
|
||||
case exitCode of
|
||||
ExitFailure 124 -> do
|
||||
output $ "[check][nixpkgs-review] took longer than " <> timeout <> " and timed out"
|
||||
|
@ -34,7 +34,6 @@ module OurPrelude
|
||||
)
|
||||
where
|
||||
|
||||
import System.FilePath ((</>))
|
||||
import Control.Applicative ((<|>))
|
||||
import Control.Category ((>>>))
|
||||
import Control.Error
|
||||
@ -57,6 +56,7 @@ import Polysemy
|
||||
import Polysemy.Error hiding (note, try, tryJust)
|
||||
import qualified Process as P
|
||||
import System.Exit
|
||||
import System.FilePath ((</>))
|
||||
import System.Process.Typed
|
||||
|
||||
interpolate :: QuasiQuoter
|
||||
|
@ -17,14 +17,14 @@ import qualified Data.Set as S
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import qualified Data.Vector as V
|
||||
import qualified System.Posix.Files as F
|
||||
import qualified Git
|
||||
import qualified Utils
|
||||
import qualified System.Directory
|
||||
import OurPrelude
|
||||
import qualified System.Directory
|
||||
import qualified System.Posix.Files as F
|
||||
import Text.Parsec (parse)
|
||||
import Text.Parser.Char
|
||||
import Text.Parser.Combinators
|
||||
import qualified Utils
|
||||
|
||||
outPathsExpr :: Text
|
||||
outPathsExpr =
|
||||
@ -94,14 +94,23 @@ outPath = do
|
||||
liftIO $ T.writeFile outpathFile outPathsExpr
|
||||
liftIO $ putStrLn "[outpaths] eval start"
|
||||
currentDir <- liftIO $ System.Directory.getCurrentDirectory
|
||||
result <- ourReadProcessInterleaved_ $ proc "nix-env" [
|
||||
"-f", outpathFile,
|
||||
result <-
|
||||
ourReadProcessInterleaved_ $
|
||||
proc
|
||||
"nix-env"
|
||||
[ "-f",
|
||||
outpathFile,
|
||||
"-qaP",
|
||||
"--no-name",
|
||||
"--out-path",
|
||||
"--arg", "path", currentDir,
|
||||
"--arg", "checkMeta", "true",
|
||||
"--show-trace"]
|
||||
"--arg",
|
||||
"path",
|
||||
currentDir,
|
||||
"--arg",
|
||||
"checkMeta",
|
||||
"true",
|
||||
"--show-trace"
|
||||
]
|
||||
liftIO $ putStrLn "[outpaths] eval end"
|
||||
pure result
|
||||
|
||||
@ -163,7 +172,8 @@ parseResults = S.fromList <$> parseResultLine `sepEndBy` newline
|
||||
|
||||
parseResultLine :: CharParsing m => m ResultLine
|
||||
parseResultLine =
|
||||
ResultLine <$> (T.dropWhileEnd (== '.') <$> parseAttrpath)
|
||||
ResultLine
|
||||
<$> (T.dropWhileEnd (== '.') <$> parseAttrpath)
|
||||
<*> parseArchitecture
|
||||
<* spaces
|
||||
<*> parseOutpaths
|
||||
@ -182,7 +192,8 @@ parseOutpaths = V.fromList <$> (parseOutpath `sepBy1` char ';')
|
||||
|
||||
parseOutpath :: CharParsing m => m Outpath
|
||||
parseOutpath =
|
||||
Outpath <$> optional (try (T.pack <$> (many (noneOf "=\n") <* char '=')))
|
||||
Outpath
|
||||
<$> optional (try (T.pack <$> (many (noneOf "=\n") <* char '=')))
|
||||
<*> (T.pack <$> many (noneOf ";\n"))
|
||||
|
||||
packageRebuilds :: Set ResultLine -> Vector Text
|
||||
|
@ -16,7 +16,7 @@ import GHC.Generics
|
||||
import Network.HTTP.Client.TLS (newTlsManager)
|
||||
import OurPrelude
|
||||
import Servant.API
|
||||
import Servant.Client (BaseUrl (..), mkClientEnv, ClientM, Scheme (..), client, runClientM)
|
||||
import Servant.Client (BaseUrl (..), ClientM, Scheme (..), client, mkClientEnv, runClientM)
|
||||
import System.IO
|
||||
|
||||
baseUrl :: BaseUrl
|
||||
@ -35,9 +35,9 @@ type Project = Vector Package
|
||||
type Projects = HashMap Text Project
|
||||
|
||||
type API =
|
||||
"project" :> Capture "project_name" Text :> Get '[JSON] Project :<|>
|
||||
"projects" :> QueryParam "inrepo" Text :> QueryParam "outdated" Bool :> Get '[JSON] Projects :<|>
|
||||
"projects" :> Capture "name" Text :> QueryParam "inrepo" Text :> QueryParam "outdated" Bool :> Get '[JSON] Projects
|
||||
"project" :> Capture "project_name" Text :> Get '[JSON] Project
|
||||
:<|> "projects" :> QueryParam "inrepo" Text :> QueryParam "outdated" Bool :> Get '[JSON] Projects
|
||||
:<|> "projects" :> Capture "name" Text :> QueryParam "inrepo" Text :> QueryParam "outdated" Bool :> Get '[JSON] Projects
|
||||
|
||||
data Package = Package
|
||||
{ repo :: Text,
|
||||
@ -56,12 +56,10 @@ api :: Proxy API
|
||||
api = Proxy
|
||||
|
||||
project :: Text -> ClientM (Vector Package)
|
||||
|
||||
projects ::
|
||||
Maybe Text ->
|
||||
Maybe Bool ->
|
||||
ClientM Projects
|
||||
|
||||
projects' ::
|
||||
Text ->
|
||||
Maybe Text ->
|
||||
|
@ -241,6 +241,7 @@ updateScript log Args {..} = do
|
||||
else do
|
||||
lift $ log "skipping because derivation has no updateScript"
|
||||
return Nothing
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Common helper functions and utilities
|
||||
-- Helper to update version and src attributes, re-computing the sha256.
|
||||
|
@ -197,8 +197,8 @@ checkResultList =
|
||||
|
||||
skipOutpathCalcList :: Skiplist
|
||||
skipOutpathCalcList =
|
||||
[ eq "firefox-beta-bin-unwrapped" "master"
|
||||
, eq "firefox-devedition-bin-unwrapped" "master"
|
||||
[ eq "firefox-beta-bin-unwrapped" "master",
|
||||
eq "firefox-devedition-bin-unwrapped" "master"
|
||||
-- "firefox-release-bin-unwrapped" is unneeded here because firefox-bin is a dependency of other packages that Hydra doesn't ignore.
|
||||
]
|
||||
|
||||
@ -234,4 +234,4 @@ python numPackageRebuilds derivationContents =
|
||||
(not isPython || numPackageRebuilds <= maxPackageRebuild)
|
||||
where
|
||||
isPython = "buildPythonPackage" `T.isInfixOf` derivationContents
|
||||
maxPackageRebuild = 25
|
||||
maxPackageRebuild = 100
|
||||
|
@ -30,7 +30,7 @@ import qualified Data.Set as S
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Data.Time.Calendar (showGregorian)
|
||||
import Data.Time.Clock (getCurrentTime, utctDay, addUTCTime, UTCTime)
|
||||
import Data.Time.Clock (UTCTime, addUTCTime, getCurrentTime, utctDay)
|
||||
import qualified GH
|
||||
import qualified Git
|
||||
import Language.Haskell.TH.Env (envQ)
|
||||
@ -41,6 +41,8 @@ import OurPrelude
|
||||
import qualified Outpaths
|
||||
import qualified Rewrite
|
||||
import qualified Skiplist
|
||||
import System.Directory (doesDirectoryExist, withCurrentDirectory)
|
||||
import System.Posix.Directory (createDirectory)
|
||||
import Utils
|
||||
( Boundary (..),
|
||||
Options (..),
|
||||
@ -55,8 +57,6 @@ import Utils
|
||||
import qualified Utils as U
|
||||
import qualified Version
|
||||
import Prelude hiding (log)
|
||||
import System.Directory (doesDirectoryExist, withCurrentDirectory)
|
||||
import System.Posix.Directory (createDirectory)
|
||||
|
||||
default (T.Text)
|
||||
|
||||
@ -181,7 +181,8 @@ updatePackageBatch simpleLog updateInfoLine updateEnv@UpdateEnv {..} = do
|
||||
Right foundAttrPath -> do
|
||||
log <- alsoLogToAttrPath foundAttrPath simpleLog
|
||||
log updateInfoLine
|
||||
mergeBase <- if batchUpdate options
|
||||
mergeBase <-
|
||||
if batchUpdate options
|
||||
then Git.mergeBase
|
||||
else pure "HEAD"
|
||||
withWorktree mergeBase foundAttrPath updateEnv $
|
||||
@ -198,11 +199,13 @@ checkExistingUpdate log updateEnv existingCommitMsg attrPath = do
|
||||
Nothing -> lift $ log "No auto update branch exists"
|
||||
Just msg -> do
|
||||
let nV = newVersion updateEnv
|
||||
lift $ log
|
||||
lift $
|
||||
log
|
||||
[interpolate|An auto update branch exists with message `$msg`. New version is $nV.|]
|
||||
|
||||
case U.titleVersion msg of
|
||||
Just branchV | Version.matchVersion (RangeMatcher (Including nV) Unbounded) branchV ->
|
||||
Just branchV
|
||||
| Version.matchVersion (RangeMatcher (Including nV) Unbounded) branchV ->
|
||||
throwError "An auto update branch exists with an equal or greater version"
|
||||
_ ->
|
||||
lift $ log "The auto update branch does not match or exceed the new version."
|
||||
@ -329,7 +332,7 @@ updateAttrPath log mergeBase updateEnv@UpdateEnv {..} attrPath = do
|
||||
|
||||
when hasUpdateScript do
|
||||
changedFiles <- Git.diffFileNames mergeBase
|
||||
let rewrittenFile = case changedFiles of { [f] -> f; _ -> derivationFile }
|
||||
let rewrittenFile = case changedFiles of [f] -> f; _ -> derivationFile
|
||||
assertNotUpdatedOn updateEnv' rewrittenFile "master"
|
||||
assertNotUpdatedOn updateEnv' rewrittenFile "staging"
|
||||
assertNotUpdatedOn updateEnv' rewrittenFile "staging-next"
|
||||
@ -356,7 +359,9 @@ updateAttrPath log mergeBase updateEnv@UpdateEnv {..} attrPath = do
|
||||
then "Outpath calculations were skipped for this package; total number of rebuilds unknown."
|
||||
else Outpaths.outpathReport opDiff
|
||||
let prBase =
|
||||
flip fromMaybe skipOutpathBase
|
||||
flip
|
||||
fromMaybe
|
||||
skipOutpathBase
|
||||
if Outpaths.numPackageRebuilds opDiff <= 500
|
||||
then "master"
|
||||
else "staging"
|
||||
@ -437,7 +442,9 @@ publishPackage log updateEnv oldSrcUrl newSrcUrl attrPath result opReport prBase
|
||||
let ghUser = GH.untagName . githubUser . options $ updateEnv
|
||||
let mkPR = if branchExists then GH.prUpdate else GH.pr
|
||||
(reusedPR, pullRequestUrl) <- mkPR updateEnv (prTitle updateEnv attrPath) prMsg (ghUser <> ":" <> (branchName updateEnv)) prBase
|
||||
when branchExists $ liftIO $ log
|
||||
when branchExists $
|
||||
liftIO $
|
||||
log
|
||||
if reusedPR
|
||||
then "Updated existing PR"
|
||||
else "Reused existing auto update branch, but no corresponding open PR was found, so created a new PR"
|
||||
@ -611,7 +618,8 @@ untilOfBorgFree log waitUntil = do
|
||||
stats <-
|
||||
shell "curl -s https://events.ofborg.org/stats.php" & readProcessInterleaved_
|
||||
waiting <-
|
||||
shell (jqBin <> " .evaluator.messages.waiting") & setStdin (byteStringInput stats)
|
||||
shell (jqBin <> " .evaluator.messages.waiting")
|
||||
& setStdin (byteStringInput stats)
|
||||
& readProcessInterleaved_
|
||||
& fmap (BSL.readInt >>> fmap fst >>> fromMaybe 0)
|
||||
when (waiting > 2) $ do
|
||||
@ -695,8 +703,7 @@ cveReport updateEnv =
|
||||
doCachix :: MonadIO m => (Text -> m ()) -> UpdateEnv -> Text -> ExceptT Text m Text
|
||||
doCachix log updateEnv resultPath =
|
||||
let o = options updateEnv
|
||||
in
|
||||
if batchUpdate o && "r-ryantm" == (GH.untagName $ githubUser o)
|
||||
in if batchUpdate o && "r-ryantm" == (GH.untagName $ githubUser o)
|
||||
then do
|
||||
lift $ log ("cachix " <> (T.pack . show) resultPath)
|
||||
Nix.cachix resultPath
|
||||
@ -737,7 +744,6 @@ updatePackage o updateInfo = do
|
||||
UpdatePackageSuccess -> do
|
||||
log $ "[result] Success updating " <> updateInfoLine
|
||||
|
||||
|
||||
withWorktree :: Text -> Text -> UpdateEnv -> IO a -> IO a
|
||||
withWorktree branch attrpath updateEnv action = do
|
||||
bracket
|
||||
@ -747,8 +753,10 @@ withWorktree branch attrpath updateEnv action = do
|
||||
Git.worktreeRemove path
|
||||
Git.delete1 (branchName updateEnv)
|
||||
Git.worktreeAdd path branch updateEnv
|
||||
pure path)
|
||||
pure path
|
||||
)
|
||||
( \path -> do
|
||||
Git.worktreeRemove path
|
||||
Git.delete1 (branchName updateEnv))
|
||||
Git.delete1 (branchName updateEnv)
|
||||
)
|
||||
(\path -> withCurrentDirectory path action)
|
||||
|
15
src/Utils.hs
15
src/Utils.hs
@ -27,7 +27,7 @@ module Utils
|
||||
regDirMode,
|
||||
outpathCacheDir,
|
||||
cacheDir,
|
||||
worktreeDir
|
||||
worktreeDir,
|
||||
)
|
||||
where
|
||||
|
||||
@ -48,10 +48,10 @@ import Database.SQLite.Simple.ToField (ToField, toField)
|
||||
import qualified GitHub as GH
|
||||
import OurPrelude
|
||||
import Polysemy.Output
|
||||
import System.Directory (doesDirectoryExist, createDirectoryIfMissing)
|
||||
import System.Directory (createDirectoryIfMissing, doesDirectoryExist)
|
||||
import System.Environment (lookupEnv)
|
||||
import System.Posix.Directory (createDirectory)
|
||||
import System.Posix.Env (getEnv)
|
||||
import System.Environment (lookupEnv)
|
||||
import System.Posix.Files
|
||||
( directoryMode,
|
||||
fileExist,
|
||||
@ -141,7 +141,10 @@ titleVersion title = if T.null prefix then Nothing else Just suffix
|
||||
|
||||
regDirMode :: FileMode
|
||||
regDirMode =
|
||||
directoryMode .|. ownerModes .|. groupModes .|. otherReadMode
|
||||
directoryMode
|
||||
.|. ownerModes
|
||||
.|. groupModes
|
||||
.|. otherReadMode
|
||||
.|. otherExecuteMode
|
||||
|
||||
logsDirectory :: MonadIO m => ExceptT Text m FilePath
|
||||
@ -214,7 +217,9 @@ logDir :: IO FilePath
|
||||
logDir = do
|
||||
r <-
|
||||
runExceptT
|
||||
( logsDirectory <|> xdgRuntimeDir <|> tmpRuntimeDir
|
||||
( logsDirectory
|
||||
<|> xdgRuntimeDir
|
||||
<|> tmpRuntimeDir
|
||||
<|> throwE
|
||||
"Failed to create log directory."
|
||||
)
|
||||
|
@ -8,8 +8,8 @@ module Version
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Foldable (toList)
|
||||
import Data.Char (isAlpha, isDigit)
|
||||
import Data.Foldable (toList)
|
||||
import Data.Function (on)
|
||||
import qualified Data.PartialOrd as PO
|
||||
import qualified Data.Text as T
|
||||
|
@ -1,8 +1,8 @@
|
||||
module CheckSpec where
|
||||
|
||||
import qualified Check
|
||||
import qualified Data.Text as T
|
||||
import Test.Hspec
|
||||
import qualified Check
|
||||
|
||||
main :: IO ()
|
||||
main = hspec spec
|
||||
|
Loading…
Reference in New Issue
Block a user