diff --git a/.github/workflows/test-ff-matrix.yml b/.github/workflows/test-ff-matrix.yml index c4266614a19..b635a78f930 100644 --- a/.github/workflows/test-ff-matrix.yml +++ b/.github/workflows/test-ff-matrix.yml @@ -1,199 +1,54 @@ -# Tests all documents in the feature-format matrix name: Feature-Format Tests on: workflow_dispatch: + inputs: + extra-r-packages: + description: "extra R package to install for the runs (like a dev version of one of the deps) - comma separated, passed to renv::install" + required: false + type: string + default: "" schedule: # run daily at 1am UTC - cron: "0 1 * * *" - # Deactivating run on commits for now - ## push: - ## branches: [main] - ## paths-ignore: - ## - "news/**" - ## - "src/resources/language/**" - ## pull_request: - ## branches: [main] - ## paths-ignore: - ## - "src/resources/language/**" + push: + branches: [main] + paths-ignore: + - "news/**" + - "src/resources/language/**" + - ".github/workflows/create-release.yml" + - ".github/workflows/performance-check.yml" + - ".github/workflows/stale-needs-repro.yml" + - ".github/workflows/test-bundle.yml" + - ".github/workflows/test-smokes-parallel.yml" + - ".github/workflows/test-quarto-latexmk.yml" + - ".github/workflows/update-test-timing.yml" + pull_request: + branches: [main] + paths-ignore: + - "news/**" + - "src/resources/language/**" + - ".github/workflows/create-release.yml" + - ".github/workflows/performance-check.yml" + - ".github/workflows/stale-needs-repro.yml" + - ".github/workflows/test-bundle.yml" + - ".github/workflows/test-smokes-parallel.yml" + - ".github/workflows/test-quarto-latexmk.yml" + - ".github/workflows/update-test-timing.yml" concurrency: - # Use github.run_id on main branch - # Use github.event.pull_request.number on pull requests, so it's unique per pull request - # Use github.ref on other branches, so it's unique per branch group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: - run-smokes: + run-feature-format-tests: name: Run feature-format matrix on (${{ matrix.os }}) - if: github.event_name != 'schedule' || (github.event_name == 'schedule' && github.repository == 'quarto-dev/quarto-cli') strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Fix temp dir to use runner one (windows) - if: runner.os == 'Windows' - run: | - echo "TMPDIR=${{ runner.temp }}" >> $GITHUB_ENV - echo "TMP=${{ runner.temp }}" >> $GITHUB_ENV - echo "TEMP=${{ runner.temp }}" >> $GITHUB_ENV - shell: bash - - - name: Set up R - uses: r-lib/actions/setup-r@v2 - with: - r-version: "4.5.0" - use-public-rspm: true - # required to avoid rtools bin in path - windows-path-include-rtools: false - - - name: Install node (for Playwright, MECA) - uses: actions/setup-node@v4 - with: - node-version: 16 - - - name: Install node dependencies - if: ${{ runner.os != 'Windows' || github.event_name == 'schedule' }} - run: yarn - working-directory: ./tests/integration/playwright - shell: bash - - - name: Install Playwright Browsers - if: ${{ runner.os != 'Windows' || github.event_name == 'schedule' }} - run: npx playwright install --with-deps - working-directory: ./tests/integration/playwright - - - name: Install MECA validator - if: ${{ runner.os != 'Windows' }} - run: npm install -g meca - - - name: Set RENV_PATHS_ROOT - shell: bash - run: | - echo "RENV_PATHS_ROOT=${{ runner.temp }}/renv" >> $GITHUB_ENV - - - name: Get R and OS version - id: get-version - run: | - cat("os-version=", sessionInfo()$running, "\n", file = Sys.getenv("GITHUB_OUTPUT"), sep = "", append = TRUE) - cat("r-version=", R.Version()$version.string, "\n", file = Sys.getenv("GITHUB_OUTPUT"), sep = "", append = TRUE) - shell: Rscript {0} - - - name: Cache R packages - uses: actions/cache@v4 - with: - path: ${{ env.RENV_PATHS_ROOT }} - key: ${{ steps.get-version.outputs.os-version }}-${{ steps.get-version.outputs.r-version }}-renv-2-${{ hashFiles('tests/renv.lock') }} - restore-keys: | - ${{ steps.get-version.outputs.os-version }}-${{ steps.get-version.outputs.r-version }}-renv-2- - save-always: true - - - name: Install missing system deps - if: runner.os == 'Linux' - run: | - sudo apt-get update -y - sudo apt-get install -y libcurl4-openssl-dev - sudo apt-get install -y libxml2-utils - sudo apt-get install -y libharfbuzz-dev libfribidi-dev - - - name: Restore R packages - working-directory: tests - run: | - if (!requireNamespace('renv', quietly = TRUE)) install.packages('renv') - renv::restore() - # Install dev versions for our testing - # Use r-universe to avoid github api calls - try(install.packages('knitr', repos = 'https://yihui.r-universe.dev')) - try(install.packages('rmarkdown', repos = 'https://rstudio.r-universe.dev')) - shell: Rscript {0} - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - - - name: Install uv for Python - uses: astral-sh/setup-uv@v3 - with: - version: "0.7.4" - enable-cache: true - cache-dependency-glob: "tests/uv.lock" - - - name: Install Python and Dependencies - working-directory: tests - run: | - uv sync --frozen - - - uses: ./.github/workflows/actions/quarto-dev - - - name: Install Tinytex - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - quarto install tinytex - - - name: Cache Typst packages - uses: ./.github/actions/cache-typst - - # - name: Install Chrome - # uses: browser-actions/setup-chrome@v1 - # with: - # chrome-version: 127 - - - name: Setup Julia - uses: julia-actions/setup-julia@v2 - with: - version: "1.10" - - - name: Cache Julia Packages - uses: julia-actions/cache@v2 - - - name: Restore Julia Packages - working-directory: tests - shell: bash - run: | - # Setup IJulia with the jupyter from the Python environment - # https://julialang.github.io/IJulia.jl/stable/manual/installation/ - export JUPYTER=$(find $(dirname $(uv run --frozen which jupyter))/ -type f -name "jupyter.exe" -o -name "jupyter") - uv run --frozen julia --color=yes --project=. -e "import Pkg; Pkg.instantiate(); Pkg.build(\"IJulia\"); Pkg.precompile()" - echo "Julia Jupyter:" - julia --project=. -e "import IJulia;println(IJulia.JUPYTER);println(IJulia.find_jupyter_subcommand(\"notebook\"))" - - - name: Setup timing file for timed test - if: ${{ matrix.time-test == true }} - run: | - echo "QUARTO_TEST_TIMING=timing-for-ci.txt" >> "$GITHUB_ENV" - - # - name: Setup tmate session - # uses: mxschmitt/action-tmate@v3 - - # The Check Chromium step appears necessary to avoid a crash/hang when rendering PDFs - # https://github.com/quarto-dev/quarto-actions/issues/45#issuecomment-1562599451 - # Same fix as in quarto-actions/quarto-render - # chromium is installed in the ubuntu runners in GHA, so no need to install it - # - name: "Check Chromium" - # if: ${{ runner.os == 'Linux' }} - # run: | - # echo $(which google-chrome) - # $(which google-chrome) --headless --no-sandbox --disable-gpu --renderer-process-limit=1 https://www.chromestatus.com - # shell: bash - - - name: Run all Smoke Tests Windows - if: ${{ runner.os == 'Windows' && format('{0}', inputs.buckets) == '' && matrix.time-test == false }} - env: - # Useful as TinyTeX latest release is checked in run-test.sh - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: ./run-tests.ps1 ../dev-docs/feature-format-matrix/qmd-files/**/*.qmd - working-directory: tests - shell: pwsh - - - name: Run all Smoke Tests Linux - if: ${{ runner.os != 'Windows' && format('{0}', inputs.buckets) == '' }} - env: - # Useful as TinyTeX latest release is checked in run-test.sh - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: shopt -s globstar && ./run-tests.sh ../dev-docs/feature-format-matrix/**/*.qmd - working-directory: tests - shell: bash + os: + - ubuntu-latest + - windows-latest + uses: ./.github/workflows/test-smokes.yml + with: + buckets: '[ "../dev-docs/feature-format-matrix/qmd-files/**/*.qmd" ]' + extra-r-packages: ${{ inputs.extra-r-packages }} diff --git a/dev-docs/feature-format-matrix/qmd-files/crossref/float/custom/document.qmd b/dev-docs/feature-format-matrix/qmd-files/crossref/float/custom/document.qmd index 91950c62d22..e6a04e973d9 100644 --- a/dev-docs/feature-format-matrix/qmd-files/crossref/float/custom/document.qmd +++ b/dev-docs/feature-format-matrix/qmd-files/crossref/float/custom/document.qmd @@ -7,6 +7,8 @@ crossref: reference-prefix: Diagram format: docusaurus-md: {} +_quarto: + tests-on-ci: false --- ::: {#dia-1} diff --git a/dev-docs/feature-format-matrix/qmd-files/crossref/float/table/document.qmd b/dev-docs/feature-format-matrix/qmd-files/crossref/float/table/document.qmd index f3ba1d839bf..1fb491e23ae 100644 --- a/dev-docs/feature-format-matrix/qmd-files/crossref/float/table/document.qmd +++ b/dev-docs/feature-format-matrix/qmd-files/crossref/float/table/document.qmd @@ -9,10 +9,12 @@ format: comment: Missing implementation pdf: *tested typst: - output-ext: typ # for the test below + keep-typ: true quality: 2 docusaurus-md: *tested - revealjs: *tested + revealjs: + quality: 2 + auto-stretch: false beamer: output-ext: tex quality: 2 @@ -38,8 +40,8 @@ _quarto: - "div#tbl-2.quarto-float figure.quarto-float.quarto-float-tbl img" - "div#tbl-1.quarto-float figure.quarto-float.quarto-float-tbl figcaption" - "div#tbl-2.quarto-float figure.quarto-float.quarto-float-tbl figcaption" - - "a[href=\"#crossreferenceable-tables\"].quarto-xref" - - "a[href=\"#as-images\"].quarto-xref" + - "a[href=\"#/tbl-1\"].quarto-xref" + - "a[href=\"#/tbl-2\"].quarto-xref" latex: &latex-tests ensureFileRegexMatches: - @@ -51,12 +53,12 @@ _quarto: - "\\\\includegraphics.*media.*table\\.jpg" beamer: *latex-tests typst: - ensureFileRegexMatches: + ensureTypstFileRegexMatches: - - - "\\" - - "\\" - - "@tbl-1" - - "@tbl-2" + - '\' + - '\' + - '#ref\(\, supplement: \[Table\]\)' + - '#ref\(\, supplement: \[Table\]\)' docusaurus-md: ensureFileRegexMatches: - diff --git a/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/code-python-label.qmd b/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/code-python-label.qmd index 573fc5ce3ff..1f3027c5063 100644 --- a/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/code-python-label.qmd +++ b/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/code-python-label.qmd @@ -18,9 +18,9 @@ _quarto: typst: ensureTypstFileRegexMatches: - - - "#align\\(right\\)\\[(\r\n?|\n)#box" + - '#align\(right\)\[(\r\n?|\n)?#box' - - - "#block\\[(\r\n?|\n)#align\\(right\\)\\[" + - '#block\[(\r\n?|\n)?#align\(right\)\[' --- diff --git a/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/code-python-nocaption.qmd b/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/code-python-nocaption.qmd index aaf5d44d433..76bcb603685 100644 --- a/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/code-python-nocaption.qmd +++ b/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/code-python-nocaption.qmd @@ -18,9 +18,9 @@ _quarto: typst: ensureTypstFileRegexMatches: - - - "#align\\(right\\)\\[(\r\n?|\n)#box" + - '#align\(right\)\[(\r\n?|\n)?#box' - - - "#block\\[(\r\n?|\n)#align\\(right\\)\\[" + - '#block\[(\r\n?|\n)?#align\(right\)\[' --- diff --git a/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/code-r-nocaption.qmd b/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/code-r-nocaption.qmd index 25b7f227286..c1d832763a2 100644 --- a/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/code-r-nocaption.qmd +++ b/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/code-r-nocaption.qmd @@ -18,9 +18,9 @@ _quarto: typst: ensureTypstFileRegexMatches: - - - "#align\\(right\\)\\[(\r\n?|\n)#box" + - '#align\(right\)\[(\r\n?|\n)?#box' - - - "#block\\[(\r\n?|\n)#align\\(right\\)\\[" + - '#block\[(\r\n?|\n)?#align\(right\)\[' --- ```{r} diff --git a/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/toplevel-id-caption.qmd b/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/toplevel-id-caption.qmd index a47ff09a48c..8e4514a3579 100644 --- a/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/toplevel-id-caption.qmd +++ b/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/toplevel-id-caption.qmd @@ -13,12 +13,13 @@ format: pptx: quality: -1 keep-typ: true +keep-tex: true _quarto: tests: - latex: - ensureFileRegexMatches: + pdf: + ensureLatexFileRegexMatches: - - - '\\hfill\\includegraphics\{100.png\}' + - '\\hfill\\pandocbounded\{\\includegraphics\[keepaspectratio\]\{100.png\}' - [] typst: ensureTypstFileRegexMatches: diff --git a/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/toplevel-id-nocaption.qmd b/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/toplevel-id-nocaption.qmd index 7429e510d8a..5263ed1ab68 100644 --- a/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/toplevel-id-nocaption.qmd +++ b/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/toplevel-id-nocaption.qmd @@ -13,12 +13,13 @@ format: pptx: quality: -1 keep-typ: true +keep-tex: true _quarto: tests: - latex: - ensureFileRegexMatches: + pdf: + ensureLatexFileRegexMatches: - - - '\\hfill\\includegraphics\{100.png\}' + - '\\hfill\\pandocbounded\{\\includegraphics\[keepaspectratio\]\{100.png\}' - [] typst: ensureTypstFileRegexMatches: diff --git a/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/toplevel-noid-nocaption.qmd b/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/toplevel-noid-nocaption.qmd index fcedceb297e..3a9980da713 100644 --- a/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/toplevel-noid-nocaption.qmd +++ b/dev-docs/feature-format-matrix/qmd-files/layout/fig-align/toplevel-noid-nocaption.qmd @@ -18,9 +18,9 @@ _quarto: typst: ensureTypstFileRegexMatches: - - - "#align\\(right\\)\\[(\r\n?|\n)#box" + - '#align\(right\)\[(\r\n?|\n)?#box' - - - "#block\\[(\r\n?|\n)#align\\(right\\)\\[" + - '#block\[(\r\n?|\n)?#align\(right\)\[' --- ![](100.png){fig-align="right"} diff --git a/dev-docs/feature-format-matrix/qmd-files/mermaid/document.qmd b/dev-docs/feature-format-matrix/qmd-files/mermaid/document.qmd index 09e54430778..1f8a1e4e73b 100644 --- a/dev-docs/feature-format-matrix/qmd-files/mermaid/document.qmd +++ b/dev-docs/feature-format-matrix/qmd-files/mermaid/document.qmd @@ -2,6 +2,8 @@ title: Mermaid format: docusaurus-md: {} +_quarto: + tests-on-ci: false --- ::: {.content-visible when-format="docusaurus-md"} diff --git a/dev-docs/feature-format-matrix/qmd-files/raw-blocks/interpreted/pandoc-native/document.qmd b/dev-docs/feature-format-matrix/qmd-files/raw-blocks/interpreted/pandoc-native/document.qmd index 116689039d3..aac82eb5869 100644 --- a/dev-docs/feature-format-matrix/qmd-files/raw-blocks/interpreted/pandoc-native/document.qmd +++ b/dev-docs/feature-format-matrix/qmd-files/raw-blocks/interpreted/pandoc-native/document.qmd @@ -29,9 +29,8 @@ _quarto: - [] typst: ensureTypstFileRegexMatches: - - - - '#figure\(\s*align\(center\)\[#table\(' - - [] + - ['#table\('] + - ['#figure\(\s*align\(center\)\[#table\('] latex: ensureFileRegexMatches: - diff --git a/src/resources/filters/quarto-post/typst.lua b/src/resources/filters/quarto-post/typst.lua index 8550ff5bf96..9450717d99d 100644 --- a/src/resources/filters/quarto-post/typst.lua +++ b/src/resources/filters/quarto-post/typst.lua @@ -36,7 +36,7 @@ function render_typst() return float end if float.content.t == "Table" then - -- this needs the fix from https://github.com/jgm/pandoc/pulls/9778 + -- this needs the fix from https://github.com/jgm/pandoc/pull/9778 float.content.classes:insert("typst-no-figure") else float.content = _quarto.ast.walk(float.content, { diff --git a/tests/smoke/smoke-all.test.ts b/tests/smoke/smoke-all.test.ts index 5562c430428..efeaea4439a 100644 --- a/tests/smoke/smoke-all.test.ts +++ b/tests/smoke/smoke-all.test.ts @@ -46,6 +46,7 @@ import { basename, dirname, join, relative } from "../../src/deno_ral/path.ts"; import { WalkEntry } from "../../src/deno_ral/fs.ts"; import { quarto } from "../../src/quarto.ts"; import { safeExistsSync, safeRemoveSync } from "../../src/core/path.ts"; +import { runningInCI } from "../../src/core/ci-info.ts"; async function fullInit() { await initYamlIntelligenceResourcesFromFilesystem(); @@ -90,6 +91,10 @@ async function guessFormat(fileName: string): Promise { return Array.from(formats); } +function skipTestOnCi(metadata: Record): boolean { + return runningInCI() && metadata["_quarto"]?.["tests-on-ci"] === false; +} + //deno-lint-ignore no-explicit-any function hasTestSpecs(metadata: any, input: string): boolean { const hasTestSpecs = metadata?.["_quarto"]?.["tests"] != undefined @@ -285,6 +290,11 @@ for (const { path: fileName } of files) { ? readYamlFromMarkdown(Deno.readTextFileSync(input)) : readYamlFromMarkdown(await jupyterNotebookToMarkdown(input, false)); + if (skipTestOnCi(metadata) === true) { + console.log(`Skipping tests for ${input} as tests-on-ci is false in metadata`); + continue; + } + const testSpecs: QuartoInlineTestSpec[] = []; if (hasTestSpecs(metadata, input)) {