From 26e5a81625c20376955dfe0736219cc90d84eec3 Mon Sep 17 00:00:00 2001 From: Caleb Sitton Date: Tue, 21 Jul 2026 10:32:50 -0600 Subject: [PATCH 1/5] ci: add github actions workflow for ci --- .github/workflows/ci.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..cc8f04e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,32 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + pre-commit: + name: Checks via pre-commit + runs-on: ubuntu-latest + + steps: + - name: Check out repository + uses: actions/checkout@v7 + + - name: Install uv + uses: astral-sh/setup-uv@v8 + with: + enable-cache: true + + - name: Install dependencies + run: uv sync --locked + + - name: Run pre-commit + run: uv run pre-commit run --all-files From 80e3fe6d7ffb554897486d3c4f6cb28c6bbe56d4 Mon Sep 17 00:00:00 2001 From: Caleb Sitton Date: Tue, 21 Jul 2026 10:50:39 -0600 Subject: [PATCH 2/5] ci: change ruff format args in pre-commit config --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8c6af73..e00fc61 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,4 +29,3 @@ repos: hooks: - id: ruff-check - id: ruff-format - args: [ --check ] From 664cdc27dd3911d82edc4db06297c0e5dd7b5a4d Mon Sep 17 00:00:00 2001 From: Caleb Sitton Date: Tue, 21 Jul 2026 11:00:21 -0600 Subject: [PATCH 3/5] ci: add mypy run to pre-commit config --- .pre-commit-config.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e00fc61..cef9089 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: - id: end-of-file-fixer - id: check-added-large-files -# Run tests, including doctests +# Project checks - repo: local hooks: - id: copyright-header @@ -22,6 +22,13 @@ repos: types: [python] always_run: true pass_filenames: false + - id: mypy + name: mypy + entry: uv run mypy dcaf/ + language: system + types: [python] + always_run: true + pass_filenames: false # Linting and formatting - repo: https://github.com/astral-sh/ruff-pre-commit From 4e4c91e0bdc2a367338141ec9a8846d0bb187af5 Mon Sep 17 00:00:00 2001 From: Caleb Sitton Date: Tue, 21 Jul 2026 11:19:44 -0600 Subject: [PATCH 4/5] ci: correct setup-uv call in workflow --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cc8f04e..956cf2d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v7 - name: Install uv - uses: astral-sh/setup-uv@v8 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 with: enable-cache: true From 4999aba2e980f75e30c1aadee45730e041316784 Mon Sep 17 00:00:00 2001 From: Caleb Sitton Date: Tue, 21 Jul 2026 11:25:17 -0600 Subject: [PATCH 5/5] ci: add missing copyright headers --- LICENSE | 2 +- dcaf/finance/opex.py | 8 +++++++- dcaf/project/contracts.py | 2 ++ dcaf/project/policies.py | 2 ++ tests/unit/test_cashflow_stream.py | 3 +-- tests/unit/test_generation.py | 2 +- tests/unit/test_generation_linked_policies.py | 6 +++++- 7 files changed, 19 insertions(+), 6 deletions(-) diff --git a/LICENSE b/LICENSE index 94554cf..a19484d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2026 Battelle Energy Alliance, LLC +Copyright (c) 2026 Battelle Energy Alliance, LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/dcaf/finance/opex.py b/dcaf/finance/opex.py index 9e489ed..4534271 100644 --- a/dcaf/finance/opex.py +++ b/dcaf/finance/opex.py @@ -10,7 +10,13 @@ from datetime import date from dcaf.finance.escalation import EscalationPolicy -from dcaf.shared.types import DayCountConvention, Period, ProFormaCategory, TaxTreatment, TimingConvention +from dcaf.shared.types import ( + DayCountConvention, + Period, + ProFormaCategory, + TaxTreatment, + TimingConvention, +) from dcaf.shared.validation import validate_finite from dcaf.streams.cashflows import CashFlowStream diff --git a/dcaf/project/contracts.py b/dcaf/project/contracts.py index f3a96fc..1466bf8 100644 --- a/dcaf/project/contracts.py +++ b/dcaf/project/contracts.py @@ -1,3 +1,5 @@ +# © 2026 Battelle Energy Alliance, LLC +# ALL RIGHTS RESERVED """Generation-linked contract terms for project-level revenue policies.""" from __future__ import annotations diff --git a/dcaf/project/policies.py b/dcaf/project/policies.py index a17a506..0d59132 100644 --- a/dcaf/project/policies.py +++ b/dcaf/project/policies.py @@ -1,3 +1,5 @@ +# © 2026 Battelle Energy Alliance, LLC +# ALL RIGHTS RESERVED """Public protocol for generation-linked project cash-flow policies.""" from __future__ import annotations diff --git a/tests/unit/test_cashflow_stream.py b/tests/unit/test_cashflow_stream.py index 29af78b..ce7d71a 100644 --- a/tests/unit/test_cashflow_stream.py +++ b/tests/unit/test_cashflow_stream.py @@ -134,8 +134,7 @@ def test_from_recurring_annual_escalation_is_date_based(): ) expected_dates = [date(2026, 4, 4), date(2026, 5, 4), date(2026, 6, 4)] expected_amounts = [ - -200.0 * _annual_factor(date(2026, 3, 5), flow_date, 0.1) - for flow_date in expected_dates + -200.0 * _annual_factor(date(2026, 3, 5), flow_date, 0.1) for flow_date in expected_dates ] for i, flow in enumerate(cf_stream.entries): assert flow.date == expected_dates[i] diff --git a/tests/unit/test_generation.py b/tests/unit/test_generation.py index ce19862..3284a20 100644 --- a/tests/unit/test_generation.py +++ b/tests/unit/test_generation.py @@ -183,7 +183,7 @@ def test_from_capacity_rejects_capacity_factor_outside_unit_interval(capacity_fa periods=1, ) - + def test_from_capacity_supports_timing_conventions(): begin = GenerationStream.from_capacity(1.0, 1.0, date(2030, 1, 1), 1, timing="begin") middle = GenerationStream.from_capacity(1.0, 1.0, date(2030, 1, 1), 1, timing="middle") diff --git a/tests/unit/test_generation_linked_policies.py b/tests/unit/test_generation_linked_policies.py index 4c3ac23..fea4fc9 100644 --- a/tests/unit/test_generation_linked_policies.py +++ b/tests/unit/test_generation_linked_policies.py @@ -1,3 +1,5 @@ +# © 2026 Battelle Energy Alliance, LLC +# ALL RIGHTS RESERVED from datetime import date from math import inf, nan from typing import cast @@ -279,7 +281,9 @@ def test_generation_revenue_callable_receives_whole_project_settlement_context() events: list[GenerationSettlementEvent] = [] def price(event: GenerationSettlementEvent) -> float: - events.append(event) # creates an external artifact that the `price` function was called for every generation event + events.append( + event + ) # creates an external artifact that the `price` function was called for every generation event return prices[event.date] analysis = (