diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..ed1fdb2 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,22 @@ +# The workflows pin actions to commit SHAs (OpenSSF Scorecard's +# Pinned-Dependencies check). A pin with no updater is a frozen dependency, +# so this is what keeps them current: dependabot reads the `# vX.Y.Z` comment +# beside each SHA to know what it's looking at. +version: 2 +updates: + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + groups: + actions: + patterns: ["*"] + + # Gemfile / Gemfile.lock: Jekyll, the plugins, and the lint gems. + - package-ecosystem: bundler + directory: "/" + schedule: + interval: weekly + groups: + gems: + patterns: ["*"] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..fe75376 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,52 @@ +name: CI + +on: + pull_request: + push: + branches: ["main"] + +permissions: + contents: read + +# Newer pushes to a PR supersede in-flight runs +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - uses: ruby/setup-ruby@e8944e80fb94b20106697132f8c20c665fab29e9 # v1.325.0 + with: + ruby-version: "3.3" + bundler-cache: true + + # Builds the site (catalog_pages.rb fails on duplicate ids and + # unresolvable persona/problem/relationship targets) then link-checks it. + - run: make test + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - uses: ruby/setup-ruby@e8944e80fb94b20106697132f8c20c665fab29e9 # v1.325.0 + with: + ruby-version: "3.3" + bundler-cache: true + + - run: pipx install yamllint + + # RuboCop over theme/_plugins, yamllint over data/ and the workflows. + - run: make lint + + # Workflow syntax and action refs. Not in `make lint` — it's a Go binary, + # not a gem, and these are the only files it checks. + - uses: docker://rhysd/actionlint@sha256:b1934ee5f1c509618f2508e6eb47ee0d3520686341fec936f3b79331f9315667 # 1.7.12 diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 402c68f..c751427 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -23,17 +23,19 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Ruby - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@e8944e80fb94b20106697132f8c20c665fab29e9 # v1.325.0 with: ruby-version: "3.3" - bundler-cache: true # runs bundle install and caches gems + bundler-cache: true # runs bundle install and caches gems - name: Setup Pages id: pages - uses: actions/configure-pages@v5 + uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0 with: # Create/enable the Pages site automatically on first run # (needs the pages: write permission granted above). @@ -46,7 +48,8 @@ jobs: JEKYLL_ENV: production - name: Upload artifact - uses: actions/upload-pages-artifact@v3 # defaults to ./_site + # defaults to ./_site + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 deploy: needs: build @@ -57,4 +60,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..1b8f484 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,21 @@ +# Lints the Jekyll plugins. The layouts and data are covered by `make test`; +# this is the only hand-written Ruby in the repo. +AllCops: + TargetRubyVersion: 3.2 + NewCops: enable + Include: + - "theme/_plugins/**/*.rb" + +# House style, and what every file here already uses. +Style/StringLiterals: + EnforcedStyle: double_quotes + +# Each plugin opens with a header comment explaining what it does; a second +# one directly above the module would just repeat it. +Style/Documentation: + Enabled: false + +# catalog_pages.rb's validator is one long linear list of guards. Splitting it +# to satisfy a length metric would scatter the checks without simplifying them. +Metrics: + Enabled: false diff --git a/.yamllint.yml b/.yamllint.yml new file mode 100644 index 0000000..bffd214 --- /dev/null +++ b/.yamllint.yml @@ -0,0 +1,18 @@ +# Style gate for the hand-edited YAML in data/ and .github/. +# Semantics are the build's job: theme/_plugins/catalog_pages.rb fails on +# duplicate ids and unresolvable references. This only keeps the formatting +# consistent for the project reps who PR against data/working-groups/. +extends: default + +rules: + # Record descriptions and notes are prose; wrapping them to 80 would mean + # reflowing paragraphs on every edit. + line-length: disable + # House style: sequences sit at their parent key's column. + indentation: + indent-sequences: consistent + # These are Jekyll data files, not documents on a stream. + document-start: disable + truthy: + # GitHub Actions' `on:` key. + allowed-values: ["true", "false", "on"] diff --git a/Gemfile b/Gemfile index b5c513d..25cecae 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,7 @@ end # Development and testing tools group :development, :test do gem "html-proofer", "~> 5.2" + gem "rubocop", "~> 1.81", require: false end # Platform-specific gems diff --git a/Gemfile.lock b/Gemfile.lock index 1b11fcb..77efa7d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,6 +5,7 @@ GEM addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) afm (1.0.0) + ast (2.4.3) async (2.39.0) console (~> 1.29) fiber-annotation @@ -109,6 +110,8 @@ GEM rexml (>= 3.4.4) kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) + language_server-protocol (3.17.0.6) + lint_roller (1.1.0) liquid (4.0.4) listen (3.10.0) logger @@ -137,6 +140,10 @@ GEM racc (~> 1.4) nokogiri (1.19.4-x86_64-linux-musl) racc (~> 1.4) + parallel (2.2.0) + parser (3.3.12.0) + ast (~> 2.4.1) + racc pathutil (0.16.2) forwardable-extended (~> 2.6) pdf-reader (2.15.1) @@ -145,6 +152,7 @@ GEM hashery (~> 2.0) ruby-rc4 ttfunk + prism (1.9.0) public_suffix (7.0.5) racc (1.8.1) rainbow (3.1.1) @@ -152,8 +160,24 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) + regexp_parser (2.12.0) rexml (3.4.4) rouge (4.7.0) + rubocop (1.91.0) + json (>= 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (>= 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.49.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.50.0) + parser (>= 3.3.7.2) + prism (~> 1.7) + ruby-progressbar (1.13.0) ruby-rc4 (0.1.5) safe_yaml (1.0.5) sass-embedded (1.99.0-aarch64-linux-gnu) @@ -206,6 +230,7 @@ DEPENDENCIES jekyll-seo-tag (~> 2.8) logger minima (~> 2.5) + rubocop (~> 1.81) tzinfo (>= 1, < 3) tzinfo-data wdm (~> 0.1) @@ -214,6 +239,7 @@ CHECKSUMS Ascii85 (2.0.1) sha256=15cb5d941808543cbb9e7e6aea3c8ec3877f154c3461e8b3673e97f7ecedbe5a addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af afm (1.0.0) sha256=5bd4d6f6241e7014ef090985ec6f4c3e9745f6de0828ddd58bc1efdd138f4545 + ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 async (2.39.0) sha256=df18730073f2bbb45788077dfa20cb365ecc1b9453969f44de6796b5191a00aa base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c @@ -257,6 +283,8 @@ CHECKSUMS json (2.19.9) sha256=9b9025b7cdddafa38d316eca0b2358488e42d417045c1b90d216a9fefe46b79a kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 + language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 + lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 liquid (4.0.4) sha256=4fcfebb1a045e47918388dbb7a0925e7c3893e58d2bd6c3b3c73ec17a2d8fdb3 listen (3.10.0) sha256=c6e182db62143aeccc2e1960033bebe7445309c7272061979bb098d03760c9d2 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 @@ -271,16 +299,23 @@ CHECKSUMS nokogiri (1.19.4-x86_64-darwin) sha256=7fd17057d3e1f00e9954a74b3cd76595d3d4a5ef233b7ed9599047c204f70551 nokogiri (1.19.4-x86_64-linux-gnu) sha256=379fae440b28915e3f19d752ce2dcf8465ed2b2fbefd2a7ca0dd497bc981a06a nokogiri (1.19.4-x86_64-linux-musl) sha256=17dfb7c1fa194ae02fbf7c51a7afc8d278045ab3fdacfd86f91d02d7b274470b + parallel (2.2.0) sha256=e1059c5fd7b649558a0aec38a769f06a42942bdb40503d005a59c352fe011cd8 + parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 pathutil (0.16.2) sha256=e43b74365631cab4f6d5e4228f812927efc9cb2c71e62976edcb252ee948d589 pdf-reader (2.15.1) sha256=18c6a986a84a3117fa49f4279fc2de51f5d2399b71833df5d2bccd595c7068ce + prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701 rb-fsevent (0.11.2) sha256=43900b972e7301d6570f64b850a5aa67833ee7d87b458ee92805d56b7318aefe rb-inotify (0.11.1) sha256=a0a700441239b0ff18eb65e3866236cd78613d6b9f78fea1f9ac47a85e47be6e + regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 rouge (4.7.0) sha256=dba5896715c0325c362e895460a6d350803dbf6427454f49a47500f3193ea739 + rubocop (1.91.0) sha256=9c82b7bf391c5d7e3798c5b9996e22a1fe3bd7468e351dfdeb96140c058296d0 + rubocop-ast (1.50.0) sha256=b9ca88300da0803ee222ad20cdb30494c0a784eed06fdc35d254b06d662788db + ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby-rc4 (0.1.5) sha256=00cc40a39d20b53f5459e7ea006a92cf584e9bc275e2a6f7aa1515510e896c03 safe_yaml (1.0.5) sha256=a6ac2d64b7eb027bdeeca1851fe7e7af0d668e133e8a88066a0c6f7087d9f848 sass-embedded (1.99.0-aarch64-linux-gnu) sha256=a46615b0295ca7bd979b9ce79f6b9f1d26881736400188bd6fd5c4b7c9b46473 diff --git a/Makefile b/Makefile index 048baee..eb3a51c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: brand-new-env-installs deps start test +.PHONY: brand-new-env-installs deps start test lint brand-new-env-installs: @command -v brew >/dev/null || { echo "Homebrew not found. Install from https://brew.sh first."; exit 1; } @@ -24,3 +24,12 @@ start: deps test: deps bundle exec jekyll build bundle exec htmlproofer ./_site --disable-external + +# yamllint is not a gem, so it isn't in the Gemfile. Use it from PATH if it's +# there, otherwise as a module (how `pip install --user` leaves it). +YAMLLINT := $(shell command -v yamllint 2>/dev/null || echo "python3 -m yamllint") + +lint: deps + bundle exec rubocop + @$(YAMLLINT) --version >/dev/null 2>&1 || { echo "yamllint not found. Install with: pip3 install yamllint"; exit 1; } + $(YAMLLINT) data/ .github/ _config.yml diff --git a/README.md b/README.md index 351eaf6..3ce460f 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,7 @@ A `Makefile` wraps the common loops (Ruby ≥ 3.2 required): make deps # bundle install (first time / after Gemfile changes) make start # serve on http://localhost:4000 make test # jekyll build + htmlproofer (run this before opening a PR) +make lint # rubocop + yamllint (needs `pip3 install yamllint`) ``` On a fresh macOS box, `make brand-new-env-installs` installs Ruby via Homebrew @@ -220,8 +221,10 @@ place to state a fact the data already carries. `make test` runs the build and link-checks the output. The build itself fails on a duplicate id or an unresolvable reference, so most mistakes surface -immediately. Run it before opening a pull request against -[`ossf/community`](https://github.com/ossf/community). +immediately. `make lint` covers formatting: yamllint over `data/` and the +workflows, RuboCop over the plugins. Run both before opening a pull request +against [`ossf/community`](https://github.com/ossf/community) — CI runs the +same two targets on every PR. ## Accessibility diff --git a/_config.yml b/_config.yml index d2c84d8..e913058 100644 --- a/_config.yml +++ b/_config.yml @@ -9,7 +9,7 @@ description: >- url: "https://tools.openssf.org" titles_from_headings: - enabled: true + enabled: true strip_title: true # Author/Project info (displayed in footer) diff --git a/data/definitions/publications.yml b/data/definitions/publications.yml index 35411ae..8b97410 100644 --- a/data/definitions/publications.yml +++ b/data/definitions/publications.yml @@ -210,7 +210,7 @@ url: https://www.cisa.gov/resources-tools/resources/vulnerability-exploitability-exchange-vex-use-cases description: >- A machine-readable statement asserting whether a known vulnerability affects a given software - artifact (and under what conditions). Pairs with SBOM and OSV records to reduce false-positive + artifact (and under what conditions). Pairs with SBOM and OSV records to reduce false-positive vuln signals. kind: publication - id: openssf-education @@ -292,7 +292,7 @@ url: https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++ description: >- This document is a guide for compiler and linker options that - contribute to delivering reliable and secure code using native (or cross) toolchains for C and C++. + contribute to delivering reliable and secure code using native (or cross) toolchains for C and C++. kind: publication - id: principles-reposec name: Principles for Package Repository Security @@ -300,7 +300,7 @@ url: https://repos.openssf.org/principles-for-package-repository-security description: >- A taxonomy of package repositories and a set of principles for their security - capabilities. This is intended to offer a set of best practices that package + capabilities. This is intended to offer a set of best practices that package repositories should strive to adhere to. kind: publication - id: oss-cna-guide @@ -316,7 +316,7 @@ aliases: [SCMBPGUIDE] url: https://best.openssf.org/SCM-BestPractices/ description: >- - Best practices for securing Source Code Manangement platforms, + Best practices for securing Source Code Manangement platforms, covering topics that include user authentication, access control, permissions, monitoring, and logging. " kind: publication @@ -344,7 +344,7 @@ url: https://github.com/ossf/oss-vulnerability-guide/blob/main/finder-guide.md#readme description: >- This guide is intended to help security researchers (aka “Finders”) - engage with open source software (OSS) project maintainers to kick + engage with open source software (OSS) project maintainers to kick off and participate in the coordinated vulnerability response process. kind: publication - id: npm-bp-guide @@ -361,7 +361,7 @@ aliases: [OSSCVDGUIDE] url: https://github.com/ossf/oss-vulnerability-guide/blob/main/maintainer-guide.md#readme description: >- - This guide is intended to help open source project maintainers create + This guide is intended to help open source project maintainers create and maintain a coordinated vulnerability response process. kind: publication - id: ossf-tech-talks @@ -407,9 +407,9 @@ url: https://openssf.org/podcast/ description: >- Get a taste for all ingredients that make up secure open - source software (SOSS) and explore the latest trends at the intersection - of AI and security, vulnerability management, and threat assessments. - Join the sharpest minds in security as they dig into challenges + source software (SOSS) and explore the latest trends at the intersection + of AI and security, vulnerability management, and threat assessments. + Join the sharpest minds in security as they dig into challenges and opportunities that create a recipe for success in making software more secure. kind: publication - id: ossf-news @@ -417,8 +417,8 @@ aliases: [OSSFNEWS] url: https://openssf.org/newsletter/ description: >- - Stay in the loop with all the latest updates and events within - our community. We invite you to join our newsletter mailing list, + Stay in the loop with all the latest updates and events within + our community. We invite you to join our newsletter mailing list, your go-to source for all the essential information about OpenSSF. kind: publication - id: ossf-research-reports diff --git a/data/working-groups/ai-ml-security.yml b/data/working-groups/ai-ml-security.yml index b845410..aea7116 100644 --- a/data/working-groups/ai-ml-security.yml +++ b/data/working-groups/ai-ml-security.yml @@ -16,7 +16,8 @@ # `status:` on a relationship is `confirmed` or `needs-review` — needs-review # means we want the project's own maintainers to check the claim. If that's # you, correcting it, setting the status to confirmed, and deleting the note -# IS the edit we're hoping for. Run `make test` before opening a PR. +# IS the edit we're hoping for. Run `make test` and `make lint` +# before opening a PR. working_group: id: ai-ml-security diff --git a/data/working-groups/bear.yml b/data/working-groups/bear.yml index 4b0ae16..9324d4c 100644 --- a/data/working-groups/bear.yml +++ b/data/working-groups/bear.yml @@ -18,7 +18,8 @@ # `status:` on a relationship is `confirmed` or `needs-review` — needs-review # means we want the project's own maintainers to check the claim. If that's # you, correcting it, setting the status to confirmed, and deleting the note -# IS the edit we're hoping for. Run `make test` before opening a PR. +# IS the edit we're hoping for. Run `make test` and `make lint` +# before opening a PR. working_group: id: bear diff --git a/data/working-groups/best-practices-wg.yml b/data/working-groups/best-practices-wg.yml index e238636..725c1ae 100644 --- a/data/working-groups/best-practices-wg.yml +++ b/data/working-groups/best-practices-wg.yml @@ -16,7 +16,8 @@ # `status:` on a relationship is `confirmed` or `needs-review` — needs-review # means we want the project's own maintainers to check the claim. If that's # you, correcting it, setting the status to confirmed, and deleting the note -# IS the edit we're hoping for. Run `make test` before opening a PR. +# IS the edit we're hoping for. Run `make test` and `make lint` +# before opening a PR. working_group: id: best-practices-wg diff --git a/data/working-groups/global-cyber-policy.yml b/data/working-groups/global-cyber-policy.yml index 83ba1c0..c53f707 100644 --- a/data/working-groups/global-cyber-policy.yml +++ b/data/working-groups/global-cyber-policy.yml @@ -18,7 +18,8 @@ # `status:` on a relationship is `confirmed` or `needs-review` — needs-review # means we want the project's own maintainers to check the claim. If that's # you, correcting it, setting the status to confirmed, and deleting the note -# IS the edit we're hoping for. Run `make test` before opening a PR. +# IS the edit we're hoping for. Run `make test` and `make lint` +# before opening a PR. working_group: id: global-cyber-policy diff --git a/data/working-groups/orbit.yml b/data/working-groups/orbit.yml index 82b47a6..922ae6c 100644 --- a/data/working-groups/orbit.yml +++ b/data/working-groups/orbit.yml @@ -16,7 +16,8 @@ # `status:` on a relationship is `confirmed` or `needs-review` — needs-review # means we want the project's own maintainers to check the claim. If that's # you, correcting it, setting the status to confirmed, and deleting the note -# IS the edit we're hoping for. Run `make test` before opening a PR. +# IS the edit we're hoping for. Run `make test` and `make lint` +# before opening a PR. working_group: id: orbit diff --git a/data/working-groups/securing-software-repositories.yml b/data/working-groups/securing-software-repositories.yml index e52b6e9..bb7016c 100644 --- a/data/working-groups/securing-software-repositories.yml +++ b/data/working-groups/securing-software-repositories.yml @@ -16,7 +16,8 @@ # `status:` on a relationship is `confirmed` or `needs-review` — needs-review # means we want the project's own maintainers to check the claim. If that's # you, correcting it, setting the status to confirmed, and deleting the note -# IS the edit we're hoping for. Run `make test` before opening a PR. +# IS the edit we're hoping for. Run `make test` and `make lint` +# before opening a PR. working_group: id: securing-software-repositories diff --git a/data/working-groups/supply-chain-integrity.yml b/data/working-groups/supply-chain-integrity.yml index e07133d..74f9515 100644 --- a/data/working-groups/supply-chain-integrity.yml +++ b/data/working-groups/supply-chain-integrity.yml @@ -16,7 +16,8 @@ # `status:` on a relationship is `confirmed` or `needs-review` — needs-review # means we want the project's own maintainers to check the claim. If that's # you, correcting it, setting the status to confirmed, and deleting the note -# IS the edit we're hoping for. Run `make test` before opening a PR. +# IS the edit we're hoping for. Run `make test` and `make lint` +# before opening a PR. working_group: id: supply-chain-integrity diff --git a/data/working-groups/uncategorized.yml b/data/working-groups/uncategorized.yml index c2a8fc9..2b7179e 100644 --- a/data/working-groups/uncategorized.yml +++ b/data/working-groups/uncategorized.yml @@ -25,7 +25,8 @@ # `status:` on a relationship is `confirmed` or `needs-review` — needs-review # means we want the project's own maintainers to check the claim. If that's # you, correcting it, setting the status to confirmed, and deleting the note -# IS the edit we're hoping for. Run `make test` before opening a PR. +# IS the edit we're hoping for. Run `make test` and `make lint` +# before opening a PR. projects: - id: bomctl @@ -277,4 +278,3 @@ projects: downstream. similar_to: [rstuf] compatible_with: [slsa, openbao] - diff --git a/data/working-groups/vulnerability-disclosures.yml b/data/working-groups/vulnerability-disclosures.yml index ff40175..bc13260 100644 --- a/data/working-groups/vulnerability-disclosures.yml +++ b/data/working-groups/vulnerability-disclosures.yml @@ -16,7 +16,8 @@ # `status:` on a relationship is `confirmed` or `needs-review` — needs-review # means we want the project's own maintainers to check the claim. If that's # you, correcting it, setting the status to confirmed, and deleting the note -# IS the edit we're hoping for. Run `make test` before opening a PR. +# IS the edit we're hoping for. Run `make test` and `make lint` +# before opening a PR. working_group: id: vulnerability-disclosures diff --git a/theme/_plugins/catalog.rb b/theme/_plugins/catalog.rb index a7821dc..e43f280 100644 --- a/theme/_plugins/catalog.rb +++ b/theme/_plugins/catalog.rb @@ -34,7 +34,7 @@ def self.build(site) groups = [] hosted = [] - (site.data[WG_DIR] || {}).sort.each do |slug, doc| + (site.data[WG_DIR] || {}).sort.each do |_slug, doc| next unless doc.is_a?(Hash) wg = doc["working_group"] @@ -53,9 +53,9 @@ def self.build(site) publications += site.data.dig("definitions", "publications") || [] site.data["catalog"] = { - "projects" => projects.sort_by { |p| p["id"].to_s }, - "publications" => publications.sort_by { |p| p["id"].to_s }, - "working_groups" => groups.sort_by { |g| g["id"].to_s }, + "projects" => projects.sort_by { |p| p["id"].to_s }, + "publications" => publications.sort_by { |p| p["id"].to_s }, + "working_groups" => groups.sort_by { |g| g["id"].to_s } } uncategorized = hosted.count { |p| p["working_group"].nil? } diff --git a/theme/_plugins/catalog_pages.rb b/theme/_plugins/catalog_pages.rb index 42a254d..3e5fef8 100644 --- a/theme/_plugins/catalog_pages.rb +++ b/theme/_plugins/catalog_pages.rb @@ -26,10 +26,10 @@ class CatalogPages < Jekyll::Generator # dir => [data path, layout name]. The layout name also gives the front # matter id key the layouts look up (`persona_id`, `project_id`, ...). TYPES = { - "personas" => [%w[definitions personas], "persona"], - "problems" => [%w[definitions problems], "problem"], - "projects" => [%w[catalog projects], "project"], - "publications" => [%w[catalog publications], "publication"], + "personas" => [%w[definitions personas], "persona"], + "problems" => [%w[definitions problems], "problem"], + "projects" => [%w[catalog projects], "project"], + "publications" => [%w[catalog publications], "publication"] }.freeze def generate(site) @@ -56,11 +56,11 @@ def build_page(site, dir, layout, record, project_count) page = Jekyll::PageWithoutAFile.new(site, site.source, dir, "#{id}.html") page.content = "" page.data.merge!( - "layout" => layout, - "title" => record["name"], - "permalink" => "/#{dir}/#{id}/", - "#{layout}_id" => id, - "description" => description_for(layout, record, project_count) + "layout" => layout, + "title" => record["name"], + "permalink" => "/#{dir}/#{id}/", + "#{layout}_id" => id, + "description" => description_for(layout, record, project_count) ) page end @@ -80,7 +80,7 @@ def description_for(layout, record, project_count) "#{name} — an OpenSSF project awaiting its persona and problem mapping." else "Which personas and problems #{name} addresses — a role-by-role and " \ - "problem-by-problem breakdown of the OpenSSF project." + "problem-by-problem breakdown of the OpenSSF project." end when "publication" "What #{name} is and which OpenSSF projects produce, consume, or relate to it." @@ -99,8 +99,10 @@ def validate!(records) records.each do |dir, list| ids = list.map { |r| r["id"] } dupes = ids.tally.select { |_, n| n > 1 }.keys - errors << "#{dir}: duplicate id(s) #{dupes.join(', ')} — the layouts' find pattern is " \ - "last-match-wins, so the later entry would silently shadow the earlier one" if dupes.any? + if dupes.any? + errors << "#{dir}: duplicate id(s) #{dupes.join(', ')} — the layouts' find pattern is " \ + "last-match-wins, so the later entry would silently shadow the earlier one" + end blank = list.reject { |r| r["id"] && r["name"] } errors << "#{dir}: #{blank.size} record(s) missing id or name" if blank.any? end