Skip to content

Commit 14c8666

Browse files
committed
Optimize GitHub Actions workflows and add catalog CI validation.
Add path-filtered PR CI with concurrency and timeouts; cache discovery pip deps; fix three CSV quoting rows so validation passes.
1 parent ded7ed0 commit 14c8666

4 files changed

Lines changed: 198 additions & 22 deletions

File tree

.github/workflows/ci.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Lightweight checks for the static dashboard and catalog.
2+
# Skipped when only docs/marketing files change (see paths filter).
3+
4+
name: CI
5+
6+
on:
7+
pull_request:
8+
paths:
9+
- "conferences.csv"
10+
- "app.js"
11+
- "index.html"
12+
- "styles.css"
13+
- "docs/**"
14+
- "scripts/**"
15+
- ".github/workflows/**"
16+
push:
17+
branches: [main]
18+
paths:
19+
- "conferences.csv"
20+
- "app.js"
21+
- "index.html"
22+
- "styles.css"
23+
- "docs/**"
24+
- "scripts/**"
25+
- ".github/workflows/**"
26+
27+
concurrency:
28+
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
29+
cancel-in-progress: true
30+
31+
permissions:
32+
contents: read
33+
34+
jobs:
35+
validate-catalog:
36+
runs-on: ubuntu-latest
37+
timeout-minutes: 5
38+
steps:
39+
- uses: actions/checkout@v4
40+
41+
- uses: actions/setup-python@v5
42+
with:
43+
python-version: "3.12"
44+
45+
- name: Validate conferences.csv
46+
run: python scripts/validate_catalog.py

.github/workflows/conference-discovery.yml

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Discovery tooling lives in discovery/ (gitignored until you choose to commit it).
2-
# Clone or copy discovery/ locally, add OPENAI_API_KEY secret, then enable this workflow.
2+
# Clone or copy discovery/ locally, add OPENAI_API_KEY secret, then push discovery/ to enable.
33

4-
name: Conference discovery (weekly)
4+
name: Conference discovery
55

66
on:
77
workflow_dispatch:
@@ -14,41 +14,52 @@ on:
1414
description: Skip OpenAI web research
1515
type: boolean
1616
default: false
17+
push:
18+
branches: [main]
19+
paths:
20+
- "discovery/**"
21+
- ".github/workflows/conference-discovery.yml"
22+
# Optional schedule — prefer monthly/biweekly over weekly to save minutes:
23+
# schedule:
24+
# - cron: "0 6 1 * *" # 06:00 UTC on the 1st of each month
1725

18-
# Uncomment when discovery/ is committed:
19-
# on:
20-
# schedule:
21-
# - cron: "0 6 * * 1"
22-
# workflow_dispatch: …
26+
concurrency:
27+
group: discovery-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
28+
cancel-in-progress: true
29+
30+
permissions:
31+
contents: read
2332

2433
jobs:
2534
discover-and-research:
26-
if: false # enable after discovery/ is in the repo
35+
# Auto-skips until discovery/ is committed (replaces hard-coded if: false).
36+
if: hashFiles('discovery/04_orchestrate/step_10_sync.py') != ''
2737
runs-on: ubuntu-latest
38+
timeout-minutes: 90
2839
steps:
2940
- uses: actions/checkout@v4
3041

31-
- name: Require discovery directory
32-
run: test -f discovery/04_orchestrate/step_10_sync.py
33-
34-
- name: Require OPENAI_API_KEY
35-
if: github.event.inputs.skip_research != 'true'
36-
run: |
37-
if [ -z "${{ secrets.OPENAI_API_KEY }}" ]; then
38-
echo "::error::Set OPENAI_API_KEY and commit discovery/ folder first."
39-
exit 1
40-
fi
41-
4242
- uses: actions/setup-python@v5
43+
id: python
4344
with:
4445
python-version: "3.12"
46+
cache: pip
47+
cache-dependency-path: discovery/02_collect/requirements.txt
4548

4649
- name: Install dependencies
4750
run: |
4851
python -m venv discovery/02_collect/.venv
4952
discovery/02_collect/.venv/bin/pip install -r discovery/02_collect/requirements.txt
5053
discovery/02_collect/.venv/bin/python -m cloakbrowser install
5154
55+
- name: Require OPENAI_API_KEY
56+
if: github.event.inputs.skip_research != 'true'
57+
run: |
58+
if [ -z "${{ secrets.OPENAI_API_KEY }}" ]; then
59+
echo "::error::Set OPENAI_API_KEY repository secret before running web research."
60+
exit 1
61+
fi
62+
5263
- name: Discovery, queue, and web research
5364
env:
5465
GITHUB_ACTIONS: true

conferences.csv

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
conference_name,priority_level,attendees_500_plus,academic_acceptance_level,submission_tracks,travel_accommodation_sponsorship,cfp_deadline_MM-DD,cft_deadline_MM-DD,cfw_deadline_MM-DD,cfv_deadline_MM-DD,conference_start_date,conference_end_date,city,country,website_or_cfp_link,cft_link,cfw_link,cfv_link,conference_type,timezone,notes,last_verified_date,venue_pattern
22
8.8 Unreal Chile,High,Yes,Mixed,Talks,Unknown,08-10,TBD,TBD,TBD,2026-10-01,2026-10-02,Santiago,Chile,https://www.papercall.io/8dot8-unreal-chile,,,,In-Person,America/Santiago,8.8 Unreal 2026 8.8 Computer Security Conference 16th year Chile; Oct 1-2 Teatro Fundación CorpArtes CA660 Rosario Norte 660 Las Condes Santiago; theme 8.8 Unreal confías en lo que ves GenAI; CFP open PaperCall closes Aug 10 2026 13:25 UTC; alternate portal https://cfp.8dot8.org/ listed Aug 31 2026 verify which portal is canonical; https://unreal.8dot8.org/ tickets https://welcu.com/8dot8/88-unreal-2026/,2026-06-01,Mostly Fixed
33
[un]prompted,High,Yes,Industry,Talks,Unknown,08-07,TBD,TBD,TBD,2026-09-07,2026-09-10,San Francisco,United States,https://unpromptedcon.org/call-for-papers/,,,,In-Person,America/Los_Angeles,AI security practitioner conference nonprofit volunteer-run; second edition Sep 7-10 2026 San Francisco per official CFP; CFP closes Aug 7 2026 notifications Aug 21 early registration until Aug 7; six tracks offense defense program building policy demos encouraged; inaugural Mar 3-4 2026 hybrid physical and online ~700 attendees The Hibernia; videos and slides at https://unpromptedcon.org/abstract-march2026/; org https://www.linkedin.com/company/unpromptedcon/,2026-06-01,Fixed
4-
ACM AsiaCCS,High,Yes,Academic,Talks,Unknown,12-12,TBD,TBD,TBD,2026-06-01,2026-06-05,Bangalore,India,https://asiaccs2026.cse.iitkgp.ac.in/important-dates/,,,,In-Person,Asia/Kolkata,Official ASIACCS 2026 site lists conference dates June 1-5 2026 in Bangalore, India,2026-03-31
5-
ACM CCS,High,Yes,Academic,Talks,Unknown,01-14,TBD,TBD,TBD,2026-11-15,2026-11-19,The Hague,Netherlands,https://www.sigsac.org/ccs/CCS2026/call-for/call-for-papers.html,,,,In-Person,Europe/Amsterdam,Official CCS 2026 site lists conference dates Nov 15-19 2026 in The Hague, Netherlands,2026-03-31
4+
ACM AsiaCCS,High,Yes,Academic,Talks,Unknown,12-12,TBD,TBD,TBD,2026-06-01,2026-06-05,Bangalore,India,https://asiaccs2026.cse.iitkgp.ac.in/important-dates/,,,,In-Person,Asia/Kolkata,"Official ASIACCS 2026 site lists conference dates June 1-5 2026 in Bangalore, India",2026-03-31,Rotating
5+
ACM CCS,High,Yes,Academic,Talks,Unknown,01-14,TBD,TBD,TBD,2026-11-15,2026-11-19,The Hague,Netherlands,https://www.sigsac.org/ccs/CCS2026/call-for/call-for-papers.html,,,,In-Person,Europe/Amsterdam,"Official CCS 2026 site lists conference dates Nov 15-19 2026 in The Hague, Netherlands",2026-03-31,Rotating
66
ACM CoNEXT,Medium,Yes,Academic,Talks,Unknown,12-12,,,TBD,2026-12-07,2026-12-11,Utrecht,Netherlands,https://conferences.sigcomm.org/co-next/2026/,,,,In-Person,Europe/Amsterdam,Primary submission round has Dec 12 deadline and conference dates are listed on official site,2026-03-30,Rotating
77
ACM IMC,High,Yes,Academic,Talks,Unknown,04-29,,,TBD,2026-10-12,2026-10-16,Karlsruhe,Germany,https://conferences.sigcomm.org/imc/2026/cfp/,,,,In-Person,Europe/Berlin,Two-cycle CFP with cycle 2 paper deadline Apr 29 and replicability track available,2026-03-30,Rotating
88
ACSAC,Medium,Yes,Academic,Talks|Workshops,Unknown,TBD,TBD,TBD,TBD,2026-12-07,2026-12-11,Los Angeles,United States,https://www.acsac.org/,,https://www.acsac.org/,,In-Person,America/Los_Angeles,2026 edition confirmed Dec 7-11 in Los Angeles CA; 2026 CFP not yet announced (2025 deadline was May 30),2026-04-01,Rotating
@@ -63,7 +63,7 @@ DeepSec,High,Yes,Mixed,Talks|Trainings|Workshops,Partial,07-31,07-31,TBD,TBD,202
6363
DeveloperWeek,High,Yes,Industry,Talks|Workshops,Yes,10-13,TBD,TBD,TBD,2024-02-21,2024-02-29,San Francisco,United States,https://www.developerweek.com/,,https://www.developerweek.com/,,In-Person,America/Los_Angeles,Main 2024 CFP closed October 13 2023,2026-03-30,Unknown
6464
DevOpsDays Salt Lake City,Medium,Yes,Industry,Talks|Workshops,Unknown,TBD,TBD,TBD,TBD,2026-05-11,2026-05-12,Salt Lake City,United States,https://slcdevopsdays.org/,,https://slcdevopsdays.org/,,In-Person,America/Denver,Estimated from recent May editions (use as planning placeholder),2026-03-30,Unknown
6565
DIMVA,Medium,Yes,Academic,Talks,Unknown,02-18,,,TBD,2026-07-01,2026-07-03,Chania,Greece,https://www.dimva.org/dimva2026/,,,,In-Person,Europe/Athens,Two-cycle CFP and cycle 2 submission deadline Feb 18 with LNCS page limits,2026-03-30,Rotating
66-
Ekoparty Buenos Aires,High,Yes,Industry,Talks|Trainings|Workshops,Yes,TBD,TBD,TBD,TBD,2026-11-01,2026-11-30,Buenos Aires,Argentina,https://www.ekoparty.org/,https://ekoparty.org/2025/12/04/call-for-tranings-buenos-aires-miami/,https://www.ekoparty.org/,,In-Person,America/Argentina/Buenos_Aires,Merged Ekoparty (2022), Ekoparty Security Conference (2024), and Ekoparty Buenos Aires into one canonical Buenos Aires row; keep current cycle tracking and retain historical continuity in this single record
66+
Ekoparty Buenos Aires,High,Yes,Industry,Talks|Trainings|Workshops,Yes,TBD,TBD,TBD,TBD,2026-11-01,2026-11-30,Buenos Aires,Argentina,https://www.ekoparty.org/,https://ekoparty.org/2025/12/04/call-for-tranings-buenos-aires-miami/,https://www.ekoparty.org/,,In-Person,America/Argentina/Buenos_Aires,"Merged Ekoparty (2022), Ekoparty Security Conference (2024), and Ekoparty Buenos Aires into one canonical Buenos Aires row; keep current cycle tracking and retain historical continuity in this single record",2026-03-30,Mostly Fixed
6767
Ekoparty Miami,Medium,Yes,Industry,Talks|Trainings,Unknown,03-20,TBD,TBD,TBD,2026-05-21,2026-05-22,Miami,United States,https://sessionize.com/ekoparty-security-conference-2026-miami/,https://sessionize.com/ekoparty-security-conference-2026-miami/,,,In-Person,America/New_York,CFP deadline was March 20 2026 (now closed); conference May 21-22 2026,2026-04-01,Unknown
6868
ESORICS,Medium,Yes,Academic,Talks,Unknown,04-21,,,TBD,2026-09-14,2026-09-18,Rome,Italy,https://www.easychair.org/cfp/ESORICS-2026,,,,In-Person,Europe/Rome,Two-cycle model and spring deadline Apr 21 with 16-page limit in CFP,2026-03-30,Rotating
6969
Ethiack,Low,No,Industry,Talks,Unknown,TBD,,,TBD,TBD,TBD,TBD,TBD,https://ethiack.com/,,,,In-Person,UTC,Added from backlog list,2026-03-30,Unknown

scripts/validate_catalog.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/env python3
2+
"""Validate conferences.csv against docs/CATALOG.md (used by CI)."""
3+
4+
from __future__ import annotations
5+
6+
import csv
7+
import re
8+
import sys
9+
from pathlib import Path
10+
11+
REPO = Path(__file__).resolve().parents[1]
12+
CSV_PATH = REPO / "conferences.csv"
13+
CATALOG_PATH = REPO / "docs" / "CATALOG.md"
14+
15+
MM_DD = re.compile(r"^(TBD|\d{2}-\d{2})$")
16+
ISO_DATE = re.compile(r"^(TBD|\d{4}-\d{2}-\d{2})$")
17+
18+
19+
def load_expected_header() -> list[str]:
20+
text = CATALOG_PATH.read_text(encoding="utf-8")
21+
for line in text.splitlines():
22+
stripped = line.strip()
23+
if stripped.startswith("conference_name,"):
24+
return stripped.split(",")
25+
raise SystemExit(f"Could not find CSV header in {CATALOG_PATH}")
26+
27+
28+
def normalize_deadline(value: str) -> str:
29+
clean = value.strip()
30+
return clean if clean else "TBD"
31+
32+
33+
def validate_mm_dd(value: str, field: str, row_num: int, errors: list[str]) -> None:
34+
clean = normalize_deadline(value)
35+
if not MM_DD.match(clean):
36+
errors.append(f"row {row_num}: invalid {field} {value!r} (expected MM-DD or TBD)")
37+
38+
39+
def validate_iso_date(value: str, field: str, row_num: int, errors: list[str]) -> None:
40+
if not ISO_DATE.match(value):
41+
errors.append(
42+
f"row {row_num}: invalid {field} {value!r} (expected YYYY-MM-DD or TBD)"
43+
)
44+
45+
46+
def main() -> int:
47+
if not CSV_PATH.is_file():
48+
print(f"::error file={CSV_PATH}::Missing conferences.csv", file=sys.stderr)
49+
return 1
50+
51+
expected = load_expected_header()
52+
errors: list[str] = []
53+
names: dict[str, int] = {}
54+
55+
with CSV_PATH.open(newline="", encoding="utf-8") as handle:
56+
reader = csv.reader(handle)
57+
try:
58+
header = next(reader)
59+
except StopIteration:
60+
print("::error::conferences.csv is empty", file=sys.stderr)
61+
return 1
62+
63+
if header != expected:
64+
errors.append(
65+
"CSV header does not match docs/CATALOG.md "
66+
f"(expected {len(expected)} columns, got {len(header)})"
67+
)
68+
69+
for row_num, row in enumerate(reader, start=2):
70+
if not any(cell.strip() for cell in row):
71+
continue
72+
if len(row) != len(expected):
73+
errors.append(
74+
f"row {row_num}: expected {len(expected)} columns, got {len(row)}"
75+
)
76+
continue
77+
78+
record = dict(zip(expected, row))
79+
name = record["conference_name"].strip()
80+
if not name:
81+
errors.append(f"row {row_num}: missing conference_name")
82+
continue
83+
84+
key = name.casefold()
85+
if key in names:
86+
errors.append(
87+
f"row {row_num}: duplicate conference_name {name!r} "
88+
f"(first seen row {names[key]})"
89+
)
90+
else:
91+
names[key] = row_num
92+
93+
for field in (
94+
"cfp_deadline_MM-DD",
95+
"cft_deadline_MM-DD",
96+
"cfw_deadline_MM-DD",
97+
"cfv_deadline_MM-DD",
98+
):
99+
validate_mm_dd(record[field].strip(), field, row_num, errors)
100+
101+
for field in (
102+
"conference_start_date",
103+
"conference_end_date",
104+
"last_verified_date",
105+
):
106+
validate_iso_date(record[field].strip(), field, row_num, errors)
107+
108+
if errors:
109+
for msg in errors:
110+
print(f"::error file={CSV_PATH}::{msg}", file=sys.stderr)
111+
print(f"::error::Found {len(errors)} catalog validation error(s)", file=sys.stderr)
112+
return 1
113+
114+
print(f"Validated {len(names)} conference row(s) in {CSV_PATH.name}")
115+
return 0
116+
117+
118+
if __name__ == "__main__":
119+
raise SystemExit(main())

0 commit comments

Comments
 (0)