Skip to content
Merged
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
24 changes: 19 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- '9.8'
- '9.10'
- '9.12'
# - '9.14'
- '9.14'
include:
- ghc_version: '9.8.1'
oldest: true
Expand All @@ -41,6 +41,23 @@ jobs:
cabal configure
--enable-test
--test-show-details=streaming
-
# TODO: Remove these exclusions as packages are updated with 9.14
if: ${{ matrix.ghc_version == '9.14' }}
name: Add 9.14 flags
run: >
cabal configure
--enable-append
--allow-newer='aeson:*'
--allow-newer='boring:*'
--allow-newer='indexed-traversable:*'
--allow-newer='indexed-traversable-instances:*'
--allow-newer='ordered-containers:*'
--allow-newer='semialign:*'
--allow-newer='text-iso8601:*'
--allow-newer='these:*'
--allow-newer='time-compat:*'
--allow-newer='uuid-types:*'
-
if: ${{ matrix.oldest }}
name: Use oldest dependencies
Expand Down Expand Up @@ -79,7 +96,7 @@ jobs:
name: Install hooky
run: |
curl -fsSL \
https://github.com/brandonchinn178/hooky/releases/download/v1.0.0/hooky-1.0.0-linux-x86_64 \
https://github.com/brandonchinn178/hooky/releases/download/v1.0.2/hooky-1.0.2-linux-x86_64 \
-o /usr/local/bin/hooky
chmod +x /usr/local/bin/hooky
-
Expand All @@ -102,9 +119,6 @@ jobs:
id: setup
name: Set up GHC
uses: haskell-actions/setup@v2
-
name: Strip unreleased section from CHANGELOG
run: sed -i -n '/^## Unreleased/d; /^## /,$p' CHANGELOG.md
-
name: Create sdist bundle
run: cabal sdist --output-directory=.
Expand Down
68 changes: 47 additions & 21 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,55 +1,81 @@
name: Release
on: workflow_dispatch

defaults:
run:
shell: bash -eu -o pipefail {0}

jobs:
cabal_file:
runs-on: ubuntu-latest
steps:
-
uses: actions/checkout@v6
-
uses: haskell-actions/parse-cabal-file@v1
id: cabal_file
with:
cabal_file: kdl-hs.cabal
outputs:
version: ${{ steps.cabal_file.outputs.version }}

ci:
uses: ./.github/workflows/ci.yml

check_changelog:
needs:
- cabal_file
runs-on: ubuntu-latest
env:
version: ${{ needs.cabal_file.outputs.version }}
steps:
-
uses: actions/checkout@v6
-
name: Validate CHANGELOG
run:
scripts/release_notes.py validate-changelog
--release-version "${version}"

release:
runs-on: ubuntu-latest
needs:
- cabal_file
- ci
- check_changelog

env:
version: ${{ needs.cabal_file.outputs.version }}

steps:
-
uses: actions/checkout@v3
uses: actions/checkout@v6
-
uses: actions/download-artifact@v4
with:
name: kdl-sdist
path: ./sdist/
-
id: cabal_file
uses: haskell-actions/parse-cabal-file@v1
with:
cabal_file: kdl-hs.cabal
-
name: Set version label
run: echo 'VERSION=v${{ steps.cabal_file.outputs.version }}' >> "${GITHUB_ENV}"
path: ./.release/sdist/
-
id: hackage_token_secret
name: Load Hackage token secret name
run: |
USERNAME="$(echo "${GITHUB_ACTOR}" | tr '[:lower:]' '[:upper:]' | tr '-' '_')"
echo "name=HACKAGE_TOKEN_${USERNAME}" >> "${GITHUB_OUTPUT}"
-
name: Get CHANGELOG section
run: |
sed '/^## Unreleased/,/^$/d' CHANGELOG.md > /tmp/changelog-without-unreleased
if [[ "$(head -n 1 /tmp/changelog-without-unreleased)" != "## ${VERSION}" ]]; then
echo "CHANGELOG doesn't look updated" >&2
exit 1
fi
sed '1 d; /^## v/,$ d' /tmp/changelog-without-unreleased > /tmp/changelog-body
name: Generate release notes
run:
scripts/release_notes.py generate
--release-version "${version}"
| tee .release/release-notes.md
-
uses: haskell-actions/hackage-publish@v1
with:
hackageToken: ${{ secrets[steps.hackage_token_secret.outputs.name] }}
packagesPath: ./sdist/
packagesPath: ./.release/sdist/
-
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ env.VERSION }}
body_path: /tmp/changelog-body
tag_name: v${{ env.version }}
body_path: .release/release-notes.md
draft: true
target_commitish: ${{ github.sha }}
2 changes: 0 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
## Unreleased

## v1.0.0

* Implement KDL v2 parser
Expand Down
1 change: 1 addition & 0 deletions kdl-hs.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ extra-source-files:
test/KDL/__snapshots__/DecoderSpec.snap.md
test/KDL/__snapshots__/ParserSpec.snap.md
test/KDL/__snapshots__/RenderSpec.snap.md
tools/kdl-test

source-repository head
type: git
Expand Down
66 changes: 66 additions & 0 deletions scripts/release_notes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env python3

import argparse
import itertools
from pathlib import Path

TOP = Path(__file__).resolve().parent.parent


def main() -> None:
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(required=True)

parser_validate_changelog = subparsers.add_parser("validate-changelog")
parser_validate_changelog.add_argument("--release-version", required=True)
parser_validate_changelog.set_defaults(
run=lambda args: validate_changelog(
version=args.release_version,
)
)

parser_generate = subparsers.add_parser("generate")
parser_generate.add_argument("--release-version", required=True)
parser_generate.set_defaults(
run=lambda args: generate(
version=args.release_version,
)
)

args = parser.parse_args()
args.run(args)


def validate_changelog(version: str) -> None:
_ = get_changelog_for(version)


def get_changelog_for(version: str) -> str:
changelog = (TOP / "CHANGELOG.md").read_text().splitlines()

if changelog[0] != f"## v{version}":
raise Exception(
f"""
CHANGELOG doesn't look updated.
Expected version: {version!r}
Got header: {changelog[0]!r}
"""
)

return "\n".join(
itertools.takewhile(
lambda line: not line.startswith("#"),
changelog[1:],
)
)


def generate(version: str) -> None:
release_notes = [
get_changelog_for(version),
]
print("\n".join(release_notes))


if __name__ == "__main__":
main()
11 changes: 8 additions & 3 deletions test/KDL/ParserSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
module KDL.ParserSpec (spec) where

import Control.Monad (forM_)
import Data.Maybe (isJust)
import Data.Text.IO qualified as Text
import KDL qualified
import Skeletest
import Skeletest.Predicate qualified as P
import System.Directory (findExecutable, listDirectory)
import System.FilePath (takeExtension, (</>))
import System.IO.Temp (withSystemTempDirectory)
import System.IO.Unsafe (unsafePerformIO)
import System.Process (callProcess)

spec :: Spec
Expand Down Expand Up @@ -44,17 +46,20 @@ spec = do
-- tested in `parse`
actual `shouldBe` expected

describe "kdl-test examples" $ do
(if dotSlashInstalled then id else skip "dotslash not installed") . describe "kdl-test examples" $ do
it "decodes correctly" $ do
decoder <- findExecutable "kdl-hs-test-decoder" >>= maybe (error "Could not find kdl-hs-test-decoder") pure
callProcess "scripts/kdl-test" ["run", "--decoder", decoder]
callProcess "tools/kdl-test" ["run", "--decoder", decoder]

it "roundtrips successfully" $ do
FixtureTmpDir tmpdir <- getFixture
let dir = tmpdir </> "kdl-examples"
callProcess "scripts/kdl-test" ["extract", "--dir", dir]
callProcess "tools/kdl-test" ["extract", "--dir", dir]
files <- filter ((== ".kdl") . takeExtension) <$> listDirectory (dir </> "valid")
forM_ files $ \file -> do
context file $ do
content <- Text.readFile (dir </> "valid" </> file)
(fmap KDL.render . KDL.parse) content `shouldBe` Right content

dotSlashInstalled :: Bool
dotSlashInstalled = unsafePerformIO $ isJust <$> findExecutable "dotslash"
File renamed without changes.