From 63790fe88913a22c6f4b5f2b17ae2684c6cbfde5 Mon Sep 17 00:00:00 2001 From: Dave Thaler Date: Thu, 25 Apr 2024 12:18:26 -0700 Subject: [PATCH] Add a workflow to validate YAML files (#159) * Add a workflow to validate YAML files The intent is that this should run on a pull request and be required to pass before the pull request can be merged. Signed-off-by: Dave Thaler * Use directories not files Signed-off-by: Dave Thaler --------- Signed-off-by: Dave Thaler Co-authored-by: Dave Thaler --- .github/workflows/update-files.yml | 194 ++++++++++++++-------------- .github/workflows/validate-yaml.yml | 26 ++++ .yamllint.yml | 7 + _config.dev.yml | 2 +- _config.yml | 4 +- _data/navigation.yml | 32 ++--- yaml-schema.yaml | 15 +-- 7 files changed, 156 insertions(+), 124 deletions(-) create mode 100644 .github/workflows/validate-yaml.yml create mode 100644 .yamllint.yml diff --git a/.github/workflows/update-files.yml b/.github/workflows/update-files.yml index 3523834..70dd2cd 100644 --- a/.github/workflows/update-files.yml +++ b/.github/workflows/update-files.yml @@ -38,100 +38,100 @@ jobs: GEDCOM_BRANCH: 'main' steps: - - name: Checkout GEDCOM.io - uses: actions/checkout@v4 - with: - path: GEDCOM.io - ref: ${{matrix.BRANCH}} - - - name: Checkout GEDCOM - if: matrix.GEDCOM_BRANCH != 'release' - uses: actions/checkout@v4 - with: - repository: FamilySearch/GEDCOM - path: GEDCOM - ref: ${{matrix.GEDCOM_BRANCH}} - - - name: Get latest release tag - if: matrix.GEDCOM_BRANCH == 'release' - id: latesttag - run: | - LATEST_TAG=$(curl --silent "https://api.github.com/repos/FamilySearch/GEDCOM/releases/latest" | jq -r .tag_name) - echo "::set-output name=tag::${LATEST_TAG}" - - - name: Checkout latest GEDCOM release - if: matrix.GEDCOM_BRANCH == 'release' - uses: actions/checkout@v4 - with: - repository: FamilySearch/GEDCOM - path: GEDCOM - ref: ${{steps.latesttag.outputs.tag}} - - - name: Generate GEDOM-tmp.md - working-directory: ${{github.workspace}}/GEDCOM/build - shell: sh - run: | - export MD_FILES=$(ls ${{ env.SPECDIR }}gedcom*.md | sort) - python3 hyperlink.py ${MD_FILES} GEDCOM-tmp.md - ls -l GEDCOM-tmp.md - - - name: Generate GEDCOM-tmp.html - working-directory: ${{github.workspace}}/GEDCOM/build - shell: sh - run: | - export MODTIME=$(git log -1 --date="format:%_d %B %Y" --format="%ad" -- ${SPECDIR}) - export PDARGS="--syntax-definition=gedcom.xml --syntax-definition=gedstruct.xml --syntax-definition=abnf.xml --from=markdown+smart --standalone --css=pandoc.css --template=template.html --toc --number-sections --self-contained --highlight-style=kate --wrap=none" - docker run --rm --volume "`pwd`:/data" pandoc/latex:2.9 GEDCOM-tmp.md -o GEDCOM-tmp.html ${PDARGS} --metadata=date:"${MODTIME}" - ls -l GEDCOM-tmp.html - - - name: Generate gedcom.html - working-directory: ${{github.workspace}}/GEDCOM/build - run: | - python3 hyperlink-code.py GEDCOM-tmp.html ../specification/gedcom.html - ls -l ../specification/gedcom.html - - - name: Install weasyprint - run: | - python3 -mpip install --user weasyprint==52.5 - - - name: Generate gedcom.pdf - working-directory: ${{github.workspace}}/GEDCOM/build - run: | - python3 -mweasyprint ../specification/gedcom.html ../specification/gedcom.pdf - ls -l ../specification/gedcom.pdf - - - name: Prep GEDCOM.io - if: matrix.GEDCOM_BRANCH == 'release' - working-directory: ${{github.workspace}}/GEDCOM/build - run: | - ls ../../GEDCOM.io - python3 push_to_gedcomio.py ../../GEDCOM.io - - - name: Set git config - env: - GH_TOKEN: ${{ github.token }} - run: | - git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com" - git config --global user.name "$(gh api /users/${GITHUB_ACTOR} | jq .name -r)" - git config -l - - - name: Check for diffs - id: diff - working-directory: ${{github.workspace}}/GEDCOM.io - run: | - git diff --quiet origin/${{matrix.BRANCH}} . || echo "::set-output name=status::changes" - shell: bash - - - name: Create Pull Request - if: steps.diff.outputs.status == 'changes' - working-directory: ${{github.workspace}}/GEDCOM.io - run: | - git checkout -b generate-${{matrix.BRANCH}}-files - git add . - git commit -m "Update generated files" - git push -f origin generate-${{matrix.BRANCH}}-files - if ! gh pr list | grep -q "generate-${{matrix.BRANCH}}-files"; then - gh pr create -B ${{matrix.BRANCH}} -H generate-${{matrix.BRANCH}}-files --title 'Update generated files' --body $'Update generated files\nThis PR is auto-generated by [gh pr create].' --label 'automated pr' - fi - env: - GH_TOKEN: ${{ github.token }} + - name: Checkout GEDCOM.io + uses: actions/checkout@v4 + with: + path: GEDCOM.io + ref: ${{matrix.BRANCH}} + + - name: Checkout GEDCOM + if: matrix.GEDCOM_BRANCH != 'release' + uses: actions/checkout@v4 + with: + repository: FamilySearch/GEDCOM + path: GEDCOM + ref: ${{matrix.GEDCOM_BRANCH}} + + - name: Get latest release tag + if: matrix.GEDCOM_BRANCH == 'release' + id: latesttag + run: | + LATEST_TAG=$(curl --silent "https://api.github.com/repos/FamilySearch/GEDCOM/releases/latest" | jq -r .tag_name) + echo "::set-output name=tag::${LATEST_TAG}" + + - name: Checkout latest GEDCOM release + if: matrix.GEDCOM_BRANCH == 'release' + uses: actions/checkout@v4 + with: + repository: FamilySearch/GEDCOM + path: GEDCOM + ref: ${{steps.latesttag.outputs.tag}} + + - name: Generate GEDOM-tmp.md + working-directory: ${{github.workspace}}/GEDCOM/build + shell: sh + run: | + export MD_FILES=$(ls ${{ env.SPECDIR }}gedcom*.md | sort) + python3 hyperlink.py ${MD_FILES} GEDCOM-tmp.md + ls -l GEDCOM-tmp.md + + - name: Generate GEDCOM-tmp.html + working-directory: ${{github.workspace}}/GEDCOM/build + shell: sh + run: | + export MODTIME=$(git log -1 --date="format:%_d %B %Y" --format="%ad" -- ${SPECDIR}) + export PDARGS="--syntax-definition=gedcom.xml --syntax-definition=gedstruct.xml --syntax-definition=abnf.xml --from=markdown+smart --standalone --css=pandoc.css --template=template.html --toc --number-sections --self-contained --highlight-style=kate --wrap=none" + docker run --rm --volume "`pwd`:/data" pandoc/latex:2.9 GEDCOM-tmp.md -o GEDCOM-tmp.html ${PDARGS} --metadata=date:"${MODTIME}" + ls -l GEDCOM-tmp.html + + - name: Generate gedcom.html + working-directory: ${{github.workspace}}/GEDCOM/build + run: | + python3 hyperlink-code.py GEDCOM-tmp.html ../specification/gedcom.html + ls -l ../specification/gedcom.html + + - name: Install weasyprint + run: | + python3 -mpip install --user weasyprint==52.5 + + - name: Generate gedcom.pdf + working-directory: ${{github.workspace}}/GEDCOM/build + run: | + python3 -mweasyprint ../specification/gedcom.html ../specification/gedcom.pdf + ls -l ../specification/gedcom.pdf + + - name: Prep GEDCOM.io + if: matrix.GEDCOM_BRANCH == 'release' + working-directory: ${{github.workspace}}/GEDCOM/build + run: | + ls ../../GEDCOM.io + python3 push_to_gedcomio.py ../../GEDCOM.io + + - name: Set git config + env: + GH_TOKEN: ${{ github.token }} + run: | + git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com" + git config --global user.name "$(gh api /users/${GITHUB_ACTOR} | jq .name -r)" + git config -l + + - name: Check for diffs + id: diff + working-directory: ${{github.workspace}}/GEDCOM.io + run: | + git diff --quiet origin/${{matrix.BRANCH}} . || echo "::set-output name=status::changes" + shell: bash + + - name: Create Pull Request + if: steps.diff.outputs.status == 'changes' + working-directory: ${{github.workspace}}/GEDCOM.io + run: | + git checkout -b generate-${{matrix.BRANCH}}-files + git add . + git commit -m "Update generated files" + git push -f origin generate-${{matrix.BRANCH}}-files + if ! gh pr list | grep -q "generate-${{matrix.BRANCH}}-files"; then + gh pr create -B ${{matrix.BRANCH}} -H generate-${{matrix.BRANCH}}-files --title 'Update generated files' --body $'Update generated files\nThis PR is auto-generated by [gh pr create].' --label 'automated pr' + fi + env: + GH_TOKEN: ${{ github.token }} diff --git a/.github/workflows/validate-yaml.yml b/.github/workflows/validate-yaml.yml new file mode 100644 index 0000000..01fd283 --- /dev/null +++ b/.github/workflows/validate-yaml.yml @@ -0,0 +1,26 @@ +# For documentation on the github environment, see +# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners +# +# For documentation on the syntax of this file, see +# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions +name: Validate-YAML + +on: + push: + branches: [main, next-minor, next-patch] + pull_request: + branches: [main, next-minor, next-patch] + +permissions: + contents: read + +jobs: + validate-yaml: + runs-on: ubuntu-latest + + steps: + - name: Checkout GEDCOM.io + uses: actions/checkout@v4 + + - name: Validate YAML + run: yamllint . _data .github .github/workflows diff --git a/.yamllint.yml b/.yamllint.yml new file mode 100644 index 0000000..bdee2f3 --- /dev/null +++ b/.yamllint.yml @@ -0,0 +1,7 @@ +# Configuration file for yamllint. For documentation, see +# https://yamllint.readthedocs.io/en/stable/configuration.html + +extends: default + +rules: + line-length: disable diff --git a/_config.dev.yml b/_config.dev.yml index 5daf820..8938cfa 100644 --- a/_config.dev.yml +++ b/_config.dev.yml @@ -2,4 +2,4 @@ url: http://127.0.0.1:4000 remote_theme: false -theme: minimal-mistakes-jekyll \ No newline at end of file +theme: minimal-mistakes-jekyll diff --git a/_config.yml b/_config.yml index c4162a5..69e9c97 100644 --- a/_config.yml +++ b/_config.yml @@ -21,7 +21,7 @@ description: >- # this means to ignore newlines until "baseurl:" baseurl: "" # the subpath of your site, e.g. /blog url: "" # the base hostname & protocol for your site, e.g. http://example.com twitter_username: FamilySearch -github_username: FamilySearch +github_username: FamilySearch repository: "FamilySearch/GEDCOM.io" # Build settings @@ -44,7 +44,7 @@ permalink: /:year/:month/:day/:title timezone: America/Denver include: - - "_pages" + - "_pages" # Analytics analytics: diff --git a/_data/navigation.yml b/_data/navigation.yml index a4524ed..a9b1780 100644 --- a/_data/navigation.yml +++ b/_data/navigation.yml @@ -19,23 +19,23 @@ specs: - title: "GEDCOM X" url: "/specs/#gedcom-x" tools: - - title: "Tools" - children: - - title: "Conversion tools" - url: "/tools/#v551-to-v70-conversion-code" - - title: "Parsers" - url: "/tools/#v70-parsers" - - title: "Development Aids" - url: "/tools/#development-aids" - - title: "Example files" - url: "/tools/#example-familysearch-gedcom-70-files" - - title: "Extension Registry" - url: "/tools/#yaml-file-format" - - title: "Other tools" - url: "/tools/#other-development-tools" + - title: "Tools" + children: + - title: "Conversion tools" + url: "/tools/#v551-to-v70-conversion-code" + - title: "Parsers" + url: "/tools/#v70-parsers" + - title: "Development Aids" + url: "/tools/#development-aids" + - title: "Example files" + url: "/tools/#example-familysearch-gedcom-70-files" + - title: "Extension Registry" + url: "/tools/#yaml-file-format" + - title: "Other tools" + url: "/tools/#other-development-tools" guides: - - title: "Guides" - children: + - title: "Guides" + children: - title: "General FAQs" url: "/guides/#general-faqs" - title: "Technical FAQs" diff --git a/yaml-schema.yaml b/yaml-schema.yaml index b02b8cc..637f505 100644 --- a/yaml-schema.yaml +++ b/yaml-schema.yaml @@ -3,11 +3,11 @@ type: object definitions: - uri: + uri: type: string simpler-pattern: "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$" pattern: "^([A-Za-z]([A-Za-z0-9]|\\+|\\-|\\.)*)\\:(//(((([-A-Z._a-z0-9]|~)|%[0-9A-Fa-f][0-9A-Fa-f]|(\\!|\\$|&|'|\\(|\\)|\\*|\\+|,|;|\\=)|\\:)*)@)?((\\[((([0-9A-Fa-f]{1,4}\\:){6}(([0-9A-Fa-f]{1,4}\\:[0-9A-Fa-f]{1,4})|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|\\:\\:([0-9A-Fa-f]{1,4}\\:){5}(([0-9A-Fa-f]{1,4}\\:[0-9A-Fa-f]{1,4})|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|([0-9A-Fa-f]{1,4})?\\:\\:([0-9A-Fa-f]{1,4}\\:){4}(([0-9A-Fa-f]{1,4}\\:[0-9A-Fa-f]{1,4})|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}\\:){,1}[0-9A-Fa-f]{1,4})?\\:\\:([0-9A-Fa-f]{1,4}\\:){3}(([0-9A-Fa-f]{1,4}\\:[0-9A-Fa-f]{1,4})|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}\\:){,2}[0-9A-Fa-f]{1,4})?\\:\\:([0-9A-Fa-f]{1,4}\\:){2}(([0-9A-Fa-f]{1,4}\\:[0-9A-Fa-f]{1,4})|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}\\:){,3}[0-9A-Fa-f]{1,4})?\\:\\:[0-9A-Fa-f]{1,4}\\:(([0-9A-Fa-f]{1,4}\\:[0-9A-Fa-f]{1,4})|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}\\:){,4}[0-9A-Fa-f]{1,4})?\\:\\:(([0-9A-Fa-f]{1,4}\\:[0-9A-Fa-f]{1,4})|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}\\:){,5}[0-9A-Fa-f]{1,4})?\\:\\:[0-9A-Fa-f]{1,4}|(([0-9A-Fa-f]{1,4}\\:){,6}[0-9A-Fa-f]{1,4})?\\:\\:)|([Vv][0-9A-Fa-f]+\\.(([-A-Z._a-z0-9]|~)|(\\!|\\$|&|'|\\(|\\)|\\*|\\+|,|;|\\=)|\\:)+))\\])|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|((([-A-Z._a-z0-9]|~)|%[0-9A-Fa-f][0-9A-Fa-f]|(\\!|\\$|&|'|\\(|\\)|\\*|\\+|,|;|\\=))*))(\\:[0-9]*)?(/(([-A-Z._a-z0-9]|~)|%[0-9A-Fa-f][0-9A-Fa-f]|(\\!|\\$|&|'|\\(|\\)|\\*|\\+|,|;|\\=)|\\:|@)*)*|/((([-A-Z._a-z0-9]|~)|%[0-9A-Fa-f][0-9A-Fa-f]|(\\!|\\$|&|'|\\(|\\)|\\*|\\+|,|;|\\=)|\\:|@)+(/(([-A-Z._a-z0-9]|~)|%[0-9A-Fa-f][0-9A-Fa-f]|(\\!|\\$|&|'|\\(|\\)|\\*|\\+|,|;|\\=)|\\:|@)*)*)?|(([-A-Z._a-z0-9]|~)|%[0-9A-Fa-f][0-9A-Fa-f]|(\\!|\\$|&|'|\\(|\\)|\\*|\\+|,|;|\\=)|\\:|@)+(/(([-A-Z._a-z0-9]|~)|%[0-9A-Fa-f][0-9A-Fa-f]|(\\!|\\$|&|'|\\(|\\)|\\*|\\+|,|;|\\=)|\\:|@)*)*|MISSING-0(([-A-Z._a-z0-9]|~)|%[0-9A-Fa-f][0-9A-Fa-f]|(\\!|\\$|&|'|\\(|\\)|\\*|\\+|,|;|\\=)|\\:|@))(\\?(((([-A-Z._a-z0-9]|~)|%[0-9A-Fa-f][0-9A-Fa-f]|(\\!|\\$|&|'|\\(|\\)|\\*|\\+|,|;|\\=)|\\:|@)|/|\\?)*))?(#(((([-A-Z._a-z0-9]|~)|%[0-9A-Fa-f][0-9A-Fa-f]|(\\!|\\$|&|'|\\(|\\)|\\*|\\+|,|;|\\=)|\\:|@)|/|\\?)*))?$" - + lang: type: string pattern: "^[a-zA-Z]{2,3}(-[a-zA-Z]{3}){0,3}|[a-zA-Z]{4,8}(-[a-zA-Z]{4})?(-[a-zA-Z]{2}|[0-9]{3})?(-[a-zA-Z]{5,8}|[0-9][a-zA-Z0-9]{3})*(-[0-9A-WY-Za-wy-z](-[a-zA-Z0-9]{2,8})+)*(-x(-[a-zA-Z0-9]{1,8})+)?|x(-[a-zA-Z0-9]{1,8})+|en-GB-oed|i-(ami|bnn|default|enochian|hak|klingon|lux|mingo|navajo|pwn|tao|tay|tsu)|sgn-(BE-(FR|NL)|CH-DE)$" @@ -75,7 +75,7 @@ properties: "$ref": "#/definitions/uris" contact: type: string - + additionalProperties: false required: @@ -98,8 +98,8 @@ allOf: then: {required: [specification]} - if: {properties: {type: {const: enumeration set}}} then: {required: [enumeration values]} - - - if: + + - if: properties: type: {const: structure} payload: @@ -107,8 +107,8 @@ allOf: pattern: '^https://gedcom.io/terms/v7/type-(List#)?Enum$' then: {required: [enumeration set]} else: {not: {required: [enumeration set]}} - - - if: + + - if: properties: type: pattern: "^(structure|enumeration|calendar|month)$" @@ -116,4 +116,3 @@ allOf: oneOf: - {required: [standard tag]} - {required: [extension tags]} -