diff --git a/.github/workflows/audit_poc_links.yml b/.github/workflows/audit_poc_links.yml index 011aa323188..d83c1460585 100644 --- a/.github/workflows/audit_poc_links.yml +++ b/.github/workflows/audit_poc_links.yml @@ -11,6 +11,7 @@ permissions: concurrency: group: repository-updates + queue: max cancel-in-progress: false jobs: @@ -20,6 +21,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v7 + with: + ref: main - name: Set up Python uses: actions/setup-python@v7 diff --git a/.github/workflows/hot_cves.yml b/.github/workflows/hot_cves.yml index a177b3495f1..ce270eeba9d 100644 --- a/.github/workflows/hot_cves.yml +++ b/.github/workflows/hot_cves.yml @@ -11,6 +11,7 @@ permissions: concurrency: group: repository-updates + queue: max cancel-in-progress: false jobs: @@ -20,6 +21,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v7 + with: + ref: main - name: Set up Python uses: actions/setup-python@v7 diff --git a/.github/workflows/site.yml b/.github/workflows/site.yml index 2205b748d9e..39752bf565f 100644 --- a/.github/workflows/site.yml +++ b/.github/workflows/site.yml @@ -15,7 +15,7 @@ permissions: concurrency: group: 'pages' - cancel-in-progress: false + cancel-in-progress: true jobs: build: @@ -30,6 +30,11 @@ jobs: with: python-version: '3.13' + - name: Verify code + run: | + python3 -m unittest discover -s tests + node --test tests/test_search.js + - name: Build site data run: python3 scripts/build_site.py @@ -68,6 +73,7 @@ jobs: deploy: needs: build runs-on: ubuntu-latest + timeout-minutes: 10 environment: name: github-pages url: ${{ steps.deploy.outputs.page_url }} diff --git a/.github/workflows/sync_collections.yml b/.github/workflows/sync_collections.yml index 188d60f6ef6..6d57a5dceea 100644 --- a/.github/workflows/sync_collections.yml +++ b/.github/workflows/sync_collections.yml @@ -11,6 +11,7 @@ permissions: concurrency: group: repository-updates + queue: max cancel-in-progress: false jobs: @@ -20,6 +21,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v7 + with: + ref: main - name: Set up Python uses: actions/setup-python@v7 diff --git a/.github/workflows/sync_cve_pocs.yml b/.github/workflows/sync_cve_pocs.yml index b1fce3329e7..1658e0e96ab 100644 --- a/.github/workflows/sync_cve_pocs.yml +++ b/.github/workflows/sync_cve_pocs.yml @@ -11,6 +11,7 @@ permissions: concurrency: group: repository-updates + queue: max cancel-in-progress: false jobs: @@ -20,6 +21,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v7 + with: + ref: main - name: Set up Python uses: actions/setup-python@v7 diff --git a/.github/workflows/sync_exploits.yml b/.github/workflows/sync_exploits.yml index 38557f60d16..6b17b0fc982 100644 --- a/.github/workflows/sync_exploits.yml +++ b/.github/workflows/sync_exploits.yml @@ -11,6 +11,7 @@ permissions: concurrency: group: repository-updates + queue: max cancel-in-progress: false jobs: @@ -20,6 +21,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v7 + with: + ref: main - name: Set up Python uses: actions/setup-python@v7 diff --git a/.github/workflows/sync_metadata.yml b/.github/workflows/sync_metadata.yml index 06b04a6275d..77a6a58d95b 100644 --- a/.github/workflows/sync_metadata.yml +++ b/.github/workflows/sync_metadata.yml @@ -18,6 +18,7 @@ permissions: concurrency: group: repository-updates + queue: max cancel-in-progress: false jobs: @@ -27,6 +28,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v7 + with: + ref: main - name: Set up Python uses: actions/setup-python@v7 diff --git a/.github/workflows/sync_nuclei.yml b/.github/workflows/sync_nuclei.yml index d21df114bb5..d8a6e0625d2 100644 --- a/.github/workflows/sync_nuclei.yml +++ b/.github/workflows/sync_nuclei.yml @@ -11,6 +11,7 @@ permissions: concurrency: group: repository-updates + queue: max cancel-in-progress: false jobs: @@ -20,6 +21,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v7 + with: + ref: main - name: Set up Python uses: actions/setup-python@v7 diff --git a/.github/workflows/sync_pocingithub.yml b/.github/workflows/sync_pocingithub.yml index a40bff5d54e..a895a9ea915 100644 --- a/.github/workflows/sync_pocingithub.yml +++ b/.github/workflows/sync_pocingithub.yml @@ -11,6 +11,7 @@ permissions: concurrency: group: repository-updates + queue: max cancel-in-progress: false jobs: @@ -20,6 +21,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v7 + with: + ref: main - name: Set up Python uses: actions/setup-python@v7 diff --git a/.gitignore b/.gitignore index ede59cec80e..f087424365f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,12 +6,15 @@ docs/repo_meta.json docs/trending_poc.json docs/nuclei.json docs/cve_metadata.json +docs/cvss.json +docs/advisories.json docs/epss.json docs/robots.txt docs/opensearch.xml docs/sitemap.xml docs/sitemap-*.xml docs/CVE-*.html +docs/[12][0-9][0-9][0-9].html docs/404.html docs/social-card.png __pycache__/ diff --git a/docs/logic.js b/docs/logic.js index 82279cda24d..a3179443287 100644 --- a/docs/logic.js +++ b/docs/logic.js @@ -1328,7 +1328,7 @@ async function loadJSON(url, options) { loadJSON('/epss.json', { cache: 'no-cache' }).then(data => { epss = data || {}; - if (state.ready && (state.query || hasActiveFilters())) renderResults(null); + if (state.ready && (state.query || hasActiveFilters())) render(); }).catch(err => console.warn(err.message)); loadJSON('/repo_meta.json', { cache: 'no-cache' }).then(data => { diff --git a/scripts/audit_poc_links.py b/scripts/audit_poc_links.py index 340c036110b..2d8ba191158 100644 --- a/scripts/audit_poc_links.py +++ b/scripts/audit_poc_links.py @@ -111,16 +111,30 @@ def survey(client: GitHubClient, names: list[str]) -> tuple[set[str], dict[str, data={"query": "query { " + aliases + " rateLimit { remaining resetAt } }"}, ) gone: set[str] = set() + failed_aliases: set[str] = set() for entry in payload.get("errors") or []: path = entry.get("path") or [] - if str(entry.get("type") or "") == "NOT_FOUND" and path: - index = str(path[0])[1:] - if index.isdigit() and int(index) < len(batch): - gone.add(batch[int(index)]) + if not path: + return set(), {} + alias = str(path[0]) + failed_aliases.add(alias) + index = alias[1:] + if ( + str(entry.get("type") or "") == "NOT_FOUND" + and len(path) == 1 + and alias.startswith("r") + and index.isdigit() + and int(index) < len(batch) + ): + gone.add(batch[int(index)]) found: dict[str, list] = {} data = payload.get("data") or {} for index, name in enumerate(batch): - repo = data.get(f"r{index}") + alias = f"r{index}" + # A failed README or root lookup is not evidence of a bare repo. + if alias in failed_aliases: + continue + repo = data.get(alias) if not repo: continue if repo_is_bare(repo, readme_text(repo)): diff --git a/scripts/build_pages.py b/scripts/build_pages.py index 3da88048d86..1e4c954eac4 100644 --- a/scripts/build_pages.py +++ b/scripts/build_pages.py @@ -230,7 +230,7 @@ def link_rows(urls: list, repo_meta: dict, *, trusted: bool = False) -> str: rows = [] for url in urls: label = url[len(GITHUB):] if url.startswith(GITHUB) else url - meta = repo_meta.get(label.lower()) if url.startswith(GITHUB) else None + meta = repo_meta.get(repo_of(url) or "") note = f"{meta[0]}★ · {esc(meta[1])}" if meta else "" rows.append( f'