Zubin pushed to branch wip/27183 at Glasgow Haskell Compiler / GHC

Commits:

3 changed files:

Changes:

  • .gitlab-ci.yml
    ... ... @@ -274,6 +274,24 @@ lint-changelog:
    274 274
         # Build changelog-d and validate all entries (checks required fields, section names, MR number)
    
    275 275
         - .gitlab/ci.sh configure
    
    276 276
         - .gitlab/ci.sh run_hadrian test --test-root-dirs="testsuite/tests/linters" --only=changelog-d
    
    277
    +    # Reject MRs that directly modify any path listed in
    
    278
    +    # changelog.d/config's markdown-targets: those files are regenerated
    
    279
    +    # from fragments at release time.
    
    280
    +    - export TOOL_OUTPUT=_build/changelog-d-markdown-targets.txt
    
    281
    +    - .gitlab/ci.sh run_hadrian list-markdown-targets
    
    282
    +    - |
    
    283
    +      paths=$(cat "$TOOL_OUTPUT")
    
    284
    +      touched=$(git diff --name-only "$base..$CI_COMMIT_SHA" -- $paths)
    
    285
    +      if [ -n "$touched" ]; then
    
    286
    +        echo "ERROR: This MR modifies a per-library changelog file directly:"
    
    287
    +        echo "$touched" | sed 's/^/  /'
    
    288
    +        echo
    
    289
    +        echo "These files are generated at release time from changelog.d/"
    
    290
    +        echo "fragments. Please add a fragment in changelog.d/ with the"
    
    291
    +        echo "appropriate 'section:' instead of editing the file directly."
    
    292
    +        echo "If this is a deliberate exception, apply the 'no-changelog' label."
    
    293
    +        exit 1
    
    294
    +      fi
    
    277 295
       dependencies: []
    
    278 296
       rules:
    
    279 297
         - if: '$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/'
    

  • hadrian/src/Rules/Changelog.hs
    ... ... @@ -7,6 +7,7 @@ import Packages
    7 7
     import Settings.Program (programContext)
    
    8 8
     
    
    9 9
     import qualified System.Directory as IO
    
    10
    +import qualified System.Environment as IO
    
    10 11
     
    
    11 12
     -- | Rules for generating and managing changelog entries.
    
    12 13
     --
    
    ... ... @@ -14,6 +15,8 @@ import qualified System.Directory as IO
    14 15
     --   hadrian/build changelog                              -- generate RST release notes
    
    15 16
     --   hadrian/build changelog --changelog-version=10.2.1   -- with explicit version
    
    16 17
     --   hadrian/build libraries-changelog-markdown           -- emit per-library Markdown bullets to stdout
    
    18
    +--   hadrian/build list-markdown-targets                  -- print one repo-relative path per
    
    19
    +--                                                          markdown-targets: row, used by CI
    
    17 20
     --   hadrian/build changelog-clear                        -- remove old entries
    
    18 21
     changelogRules :: Rules ()
    
    19 22
     changelogRules = do
    
    ... ... @@ -47,6 +50,17 @@ changelogRules = do
    47 50
                  , "--libraries-changelog-markdown"
    
    48 51
                  ]
    
    49 52
     
    
    53
    +    phony "list-markdown-targets" $ do
    
    54
    +        ctx <- programContext stage0Boot changelogD
    
    55
    +        progPath <- programPath ctx
    
    56
    +        need [progPath]
    
    57
    +        top <- topDirectory
    
    58
    +        let args = [top -/- "changelog.d/", "--list-markdown-targets"]
    
    59
    +        mOut <- liftIO $ IO.lookupEnv "TOOL_OUTPUT"
    
    60
    +        case mOut of
    
    61
    +          Nothing -> cmd_ [progPath] args
    
    62
    +          Just fp -> quietly $ (cmd (FileStdout fp) [progPath] args :: Action ())
    
    63
    +
    
    50 64
         phony "changelog-clear" $ do
    
    51 65
             top <- topDirectory
    
    52 66
             let dir = top -/- "changelog.d"
    

  • utils/changelog-d/ChangelogD.hs
    ... ... @@ -20,7 +20,7 @@ import Data.Set (Set)
    20 20
     import Data.Traversable        (for)
    
    21 21
     import System.Directory        (doesDirectoryExist, doesFileExist, listDirectory)
    
    22 22
     import System.Environment      (getArgs)
    
    23
    -import System.Exit             (exitFailure)
    
    23
    +import System.Exit             (ExitCode(..), exitFailure, exitWith)
    
    24 24
     import System.FilePath         ((</>), dropTrailingPathSeparator, takeDirectory)
    
    25 25
     import System.IO               (hPutStrLn, stderr)
    
    26 26
     
    
    ... ... @@ -72,6 +72,10 @@ usage = unlines
    72 72
         , "                                  to a single section. Without this, all"
    
    73 73
         , "                                  configured markdown-targets are emitted,"
    
    74 74
         , "                                  separated by HTML-comment markers."
    
    75
    +    , "  --list-markdown-targets         Print one repo-relative path per line for"
    
    76
    +    , "                                  every entry in `markdown-targets:`. Used"
    
    77
    +    , "                                  by CI to source the list of files MRs are"
    
    78
    +    , "                                  not allowed to edit directly."
    
    75 79
         , "  --help                          Show this help"
    
    76 80
         ]
    
    77 81
     
    
    ... ... @@ -79,13 +83,14 @@ parseArgs :: [String] -> Either String Opts
    79 83
     parseArgs = go defaultOpts
    
    80 84
       where
    
    81 85
         defaultOpts = Opts
    
    82
    -        { optDirectory  = "changelog.d"
    
    83
    -        , optVersion    = Nothing
    
    84
    -        , optValidate   = False
    
    85
    -        , optExpectMR   = Nothing
    
    86
    -        , optExpectCLC  = False
    
    87
    -        , optMarkdown   = False
    
    88
    -        , optMdSection  = Nothing
    
    86
    +        { optDirectory   = "changelog.d"
    
    87
    +        , optVersion     = Nothing
    
    88
    +        , optValidate    = False
    
    89
    +        , optExpectMR    = Nothing
    
    90
    +        , optExpectCLC   = False
    
    91
    +        , optMarkdown    = False
    
    92
    +        , optMdSection   = Nothing
    
    93
    +        , optListTargets = False
    
    89 94
             }
    
    90 95
     
    
    91 96
         go opts [] = Right opts
    
    ... ... @@ -102,6 +107,8 @@ parseArgs = go defaultOpts
    102 107
             go opts { optMarkdown = True } rest
    
    103 108
         go opts ("--section" : s : rest) = go opts { optMdSection = Just s } rest
    
    104 109
         go _    ("--section" : []) = Left "--section requires an argument"
    
    110
    +    go opts ("--list-markdown-targets" : rest) =
    
    111
    +        go opts { optListTargets = True } rest
    
    105 112
         go _    (('-':'-':opt) : _) = Left $ "Unknown option: --" ++ opt
    
    106 113
         go _    (('-':opt) : _) = Left $ "Unknown option: -" ++ opt
    
    107 114
         go opts (dir : rest) = go opts { optDirectory = dir } rest
    
    ... ... @@ -148,6 +155,10 @@ makeChangelog Opts {..} = do
    148 155
             either (exitWithExc . PlainError) return $
    
    149 156
                 parseWith parseConfig filename contents
    
    150 157
     
    
    158
    +    when optListTargets $ do
    
    159
    +        for_ (cfgMarkdownTargets cfg) (putStrLn . mtPath)
    
    160
    +        exitWith ExitSuccess
    
    161
    +
    
    151 162
         -- Read only regular files, skipping config, dotfiles, and any
    
    152 163
         -- subdirectories (e.g. golden-output dirs alongside test fragments).
    
    153 164
         dirContents <- filter (not . isTmpFile) <$> listDirectory optDirectory
    
    ... ... @@ -619,6 +630,7 @@ data Opts = Opts
    619 630
         , optExpectCLC  :: Bool             -- ^ Require entry matched by --expect-mr to have clc:
    
    620 631
         , optMarkdown   :: Bool             -- ^ Emit per-library Markdown to stdout
    
    621 632
         , optMdSection  :: Maybe String     -- ^ Restrict markdown emission to one section
    
    633
    +    , optListTargets :: Bool            -- ^ List markdown-targets paths to stdout
    
    622 634
         }
    
    623 635
       deriving (Show)
    
    624 636