Skip to content

Commit 4e62216

Browse files
authored
Merge pull request #2171 from cal-itp/update-gh-action
Update GH action to use uv for `calitp-portfolio`
2 parents 62015f5 + 47dd706 commit 4e62216

6 files changed

Lines changed: 80 additions & 22 deletions

File tree

.github/workflows/update-portfolio-index.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,17 @@ jobs:
5252
cache-python: true
5353

5454
- name: Install portfolio packages
55-
run: uv sync --group portfolio --locked --all-extras --dev
55+
run: uv sync --all-groups
56+
57+
- name: Login for portfolio
58+
run: uv run calitp-portfolio login-service-account
59+
env:
60+
service_account: ${{ env.SERVICE_ACCOUNT }}
5661

5762
- name: Deploy index Staging
5863
if: ${{ github.ref != 'refs/heads/main' }}
59-
run: uv run python portfolio/portfolio.py index --deploy --no-prod
64+
run: uv run calitp-portfolio index calitp-portfolio-sites/sites.yml --output /tmp/index.html --deploy --target staging --service-account && rm /tmp/index.html
6065

6166
- name: Deploy index Production
6267
if: ${{ github.ref == 'refs/heads/main' }}
63-
run: uv run python portfolio/portfolio.py index --deploy --prod
68+
run: uv run calitp-portfolio index calitp-portfolio-sites/sites.yml --output /tmp/index.html --deploy --target prod --service-account && rm /tmp/index.html

calitp-portfolio-sites/sites.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,21 @@ sites:
3838
- title: NTD Monthly Ridership by RTPA
3939
name: ntd_monthly_ridership
4040
source: https://github.com/cal-itp/ntd-snapshot/tree/main/monthly_ridership/
41-
- title: New Transit Performance Metrics
42-
name: new_transit_metrics
43-
source: ./ntd/new_transit_metrics/
41+
- title: UCLA NTD Transit Performance Metrics
42+
name: ucla_ntd_performance_metrics
43+
source: https://github.com/cal-itp/ntd-snapshot/tree/main/ucla_performance_metrics/
4444
- title: Potential Detour Stops using GTFS Vehicle Positions
4545
name: detour_stops
46-
source: ./rt_predictions/
46+
source: https://github.com/cal-itp/gtfs-curator/tree/main/rt_vehicle_positions/
4747
- title: SB125 Fund Split Analysis
4848
name: sb125_fund_split_analysis
4949
source: ./sb125_analyses/sb125_fund_split_analysis/
5050
- title: Thruway Bus Analysis
5151
name: thruway_intercity_bus
5252
source: ./thruway_intercity_bus/
53+
- title: Transit Events Analysis
54+
name: transit_events
55+
source: https://github.com/cal-itp/gtfs-curator/tree/main/transit_events/
5356

5457
test_sites:
5558
- title: Basic Analyses Test

calitp-portfolio/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "calitp-portfolio"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
description = "CLI for building, validating, and deploying Cal-ITP portfolio sites."
55
authors = [{ name = "Cal-ITP" }]
66
requires-python = ">=3.11.0, <3.12.0"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.1.0"
1+
__version__ = "0.1.1"

calitp-portfolio/src/calitp_portfolio/cli.py

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,14 @@ def index(
5151
output: Optional[Path] = typer.Option(None, "--output", "-o", help="Path to write rendered index.html."),
5252
target: str = typer.Option("staging", "--target", help="Deploy target: staging or prod."),
5353
deploy: bool = typer.Option(
54-
False, "--deploy", help="After rendering, upload index.html to the manifest's deploy target."
54+
False,
55+
"--deploy",
56+
help="After rendering, upload index.html to the manifest's deploy target.",
57+
),
58+
service_account: bool = typer.Option(
59+
False,
60+
"--service-account",
61+
help="For GH action only, use --service-account. Credentials pass through GH runner.",
5562
),
5663
) -> None:
5764
"""Render the portfolio landing page from a sites.yml manifest."""
@@ -68,7 +75,12 @@ def index(
6875

6976
if deploy:
7077
target_url = _resolve_target_url(manifest.deploy, target, source_label="sites.yml")
71-
_require_auth()
78+
79+
# For service account, GH action generates a hash that is used as credential
80+
if service_account:
81+
pass
82+
else:
83+
_require_auth()
7284
deployer.upload_file(target_url, output_path)
7385
typer.echo(f"deployed {output_path} -> {target_url}")
7486

@@ -100,9 +112,15 @@ def build(
100112
"-o",
101113
help="Where to write build artifacts. Defaults to `<yml dir>/<yml stem>/`.",
102114
),
103-
execute: bool = typer.Option(True, "--execute/--no-execute", help="Skip calls to papermill when --no-execute."),
115+
execute: bool = typer.Option(
116+
True,
117+
"--execute/--no-execute",
118+
help="Skip calls to papermill when --no-execute.",
119+
),
104120
show_stderr: bool = typer.Option(
105-
False, "--show-stderr", help="Keep stderr stream in cell outputs (default: strip)."
121+
False,
122+
"--show-stderr",
123+
help="Keep stderr stream in cell outputs (default: strip).",
106124
),
107125
prepare_only: bool = typer.Option(False, help="Pass-through to papermill; if true, cells are not executed."),
108126
continue_on_error: bool = typer.Option(False, help="Continue building remaining chapters on papermill error."),
@@ -115,18 +133,29 @@ def build(
115133
limit: Optional[int] = typer.Option(None, "--limit", help="Build only the first N chapters in source order."),
116134
readme_only: bool = typer.Option(False, "--readme-only", help="Build just the landing page; skip all chapters."),
117135
toc_only: bool = typer.Option(
118-
False, "--toc-only", help="Re-render myst.yml and run jupyter-book; skip papermill and readme copy."
136+
False,
137+
"--toc-only",
138+
help="Re-render myst.yml and run jupyter-book; skip papermill and readme copy.",
119139
),
120140
) -> None:
121141
"""Build a static site from a parameterized notebook portfolio."""
122142
if readme_only and toc_only:
123-
typer.secho("error: --readme-only and --toc-only are mutually exclusive", fg=typer.colors.RED)
143+
typer.secho(
144+
"error: --readme-only and --toc-only are mutually exclusive",
145+
fg=typer.colors.RED,
146+
)
124147
raise typer.Exit(code=2)
125148
if readme_only and (only or limit is not None):
126-
typer.secho("error: --readme-only cannot be combined with --only or --limit", fg=typer.colors.RED)
149+
typer.secho(
150+
"error: --readme-only cannot be combined with --only or --limit",
151+
fg=typer.colors.RED,
152+
)
127153
raise typer.Exit(code=2)
128154
if toc_only and (only or limit is not None):
129-
typer.secho("error: --toc-only cannot be combined with --only or --limit", fg=typer.colors.RED)
155+
typer.secho(
156+
"error: --toc-only cannot be combined with --only or --limit",
157+
fg=typer.colors.RED,
158+
)
130159
raise typer.Exit(code=2)
131160

132161
papermill_runs = execute and not prepare_only and not readme_only and not toc_only
@@ -181,7 +210,9 @@ def deploy(
181210
help="Directory of HTML to upload if not using site yml",
182211
),
183212
target_url: Optional[str] = typer.Option(
184-
None, "--target-url", help="gs://bucket/prefix to upload to if not using site yml"
213+
None,
214+
"--target-url",
215+
help="gs://bucket/prefix to upload to if not using site yml",
185216
),
186217
) -> None:
187218
"""Upload built HTML to GCS. Defaults to <site>/_build/html and the yml's deploy target."""
@@ -242,6 +273,15 @@ def login() -> None:
242273
raise typer.Exit(code=returncode)
243274

244275

276+
@app.command()
277+
def login_service_account() -> None:
278+
"""Authenticate to Google Cloud using the Cal-ITP login config bundled with this tool."""
279+
if auth.is_valid():
280+
returncode = 0
281+
elif returncode != 0:
282+
raise typer.Exit(code=returncode)
283+
284+
245285
_WCAG_PRESETS = {
246286
"a": ["wcag2a"],
247287
"aa": ["wcag2a", "wcag2aa", "wcag21aa"],
@@ -253,7 +293,11 @@ def login() -> None:
253293
@app.command(name="axe-check")
254294
def axe_check(
255295
site_yml: Optional[Path] = typer.Argument(
256-
None, exists=True, dir_okay=False, readable=True, help="Site yml; build dir is derived."
296+
None,
297+
exists=True,
298+
dir_okay=False,
299+
readable=True,
300+
help="Site yml; build dir is derived.",
257301
),
258302
html: Optional[Path] = typer.Option(None, "--html", exists=True, file_okay=False, help="Scan this directory."),
259303
wcag: str = typer.Option("aa", "--wcag", help="WCAG conformance level: a, aa, or aaa."),
@@ -262,10 +306,16 @@ def axe_check(
262306
"--impact",
263307
help="Comma-separated impact levels to show. Use 'all' for everything.",
264308
),
265-
no_dedupe: bool = typer.Option(False, "--no-dedupe", help="Show one entry per page instead of grouping by rule."),
309+
no_dedupe: bool = typer.Option(
310+
False,
311+
"--no-dedupe",
312+
help="Show one entry per page instead of grouping by rule.",
313+
),
266314
skip_axe_check: bool = typer.Option(False, "--skip-axe-check", help="Skip the axe CLI pre-flight."),
267315
report: bool = typer.Option(
268-
False, "--report", help=f"Write the full axe JSON report to {DEFAULT_REPORT_FILENAME} in the current directory."
316+
False,
317+
"--report",
318+
help=f"Write the full axe JSON report to {DEFAULT_REPORT_FILENAME} in the current directory.",
269319
),
270320
serve: Optional[bool] = typer.Option(
271321
None,

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)