Coverage for src/software_citation_sync/github_action.py: 84%
49 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-06-27 17:58 +0000
« prev ^ index » next coverage.py v7.14.3, created at 2026-06-27 17:58 +0000
1# SPDX-FileCopyrightText: 2026 Arcangelo Massari <github@a.arcangelomassari.com>
2#
3# SPDX-License-Identifier: ISC
5from __future__ import annotations
7import os
8from datetime import datetime, timezone
9from pathlib import Path
11from software_citation_sync.config import CitationConfig, ProjectMetadata
12from software_citation_sync.discovery import discover_project_metadata, discover_version
13from software_citation_sync.software_heritage import archive_origin
14from software_citation_sync.sync import (
15 check,
16 write_citation_metadata,
17 write_readme,
18)
20CITATION_PATH = Path("CITATION.cff")
21README_PATH = Path("README.md")
22ARCHIVE_TIMEOUT_SECONDS = 300
23ARCHIVE_POLL_INTERVAL_SECONDS = 10
26def main() -> None:
27 root = Path.cwd()
28 version = _discover_required_version(root)
29 date_released = _current_date()
30 origin_url = _current_repository_url()
31 software_heritage_url = archive_origin(
32 origin_url,
33 timeout_seconds=ARCHIVE_TIMEOUT_SECONDS,
34 poll_interval_seconds=ARCHIVE_POLL_INTERVAL_SECONDS,
35 )
36 project_metadata = _discover_required_project_metadata(root) if not CITATION_PATH.exists() else None
37 citation_config = CitationConfig(
38 citation_path=CITATION_PATH,
39 readme_path=README_PATH,
40 version=version,
41 date_released=date_released,
42 software_heritage_url=software_heritage_url,
43 )
45 citation_changed = write_citation_metadata(citation_config, project_metadata)
46 readme_changed = write_readme(citation_config)
47 check_result = check(citation_config)
48 for error in check_result.errors:
49 print(error)
50 if not check_result.ok:
51 raise SystemExit(1)
53 _set_output("changed", str(citation_changed or readme_changed).lower())
56def _discover_required_version(root: Path) -> str:
57 version = discover_version(root)
58 if version is None:
59 msg = "Software version not found in package.json or pyproject.toml"
60 raise ValueError(msg)
61 return version
64def _discover_required_project_metadata(root: Path) -> ProjectMetadata:
65 project_metadata = discover_project_metadata(root)
66 if project_metadata is None:
67 msg = "Project metadata not found in package.json or pyproject.toml"
68 raise ValueError(msg)
69 return project_metadata
72def _current_date() -> str:
73 return datetime.now(timezone.utc).date().isoformat()
76def _current_repository_url() -> str:
77 return f"{os.environ['GITHUB_SERVER_URL'].rstrip('/')}/{os.environ['GITHUB_REPOSITORY']}"
80def _set_output(name: str, value: str) -> None:
81 with Path(os.environ["GITHUB_OUTPUT"]).open("a", encoding="utf-8") as file:
82 file.write(f"{name}={value}\n")
85if __name__ == "__main__":
86 main()