Zubin pushed to branch wip/27183 at Glasgow Haskell Compiler / GHC
Commits:
-
1d33272d
by Zubin Duggal at 2026-04-28T17:28:33+05:30
3 changed files:
Changes:
| ... | ... | @@ -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.*/'
|
| ... | ... | @@ -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"
|
| ... | ... | @@ -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 |