Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .github/actions/lint-extension/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,65 @@ runs:
exit 1
fi
shell: bash

# The render-set guard below only applies to Quarto content.
- name: Detect Quarto appmode
id: quarto-appmode
run: |
APPMODE=$(jq -r '.metadata.appmode // ""' ./extensions/${{ inputs.extension-name }}/manifest.json)
if [[ "$APPMODE" == quarto-* ]]; then
echo "is-quarto=true" >> "$GITHUB_OUTPUT"
else
echo "is-quarto=false" >> "$GITHUB_OUTPUT"
fi
shell: bash

- name: Set up Quarto
if: steps.quarto-appmode.outputs.is-quarto == 'true'
uses: quarto-dev/quarto-actions/setup@v2

# Guards against the served-document bug (#392): Quarto renders every sibling
# Markdown file (e.g. CHANGELOG.md) as its own page, and with no pinned
# primary the default served document can silently flip to that page (e.g.
# CHANGELOG.html) instead of the entrypoint. Every build-time check stays
# green, so nothing else catches it. The standard is that a Quarto extension
# renders only what it serves: single-document content pins project.render to
# its entrypoint, while websites render their own pages. So this fails when a
# non-website extension renders a sibling Markdown page.
- name: Check Quarto render set
if: steps.quarto-appmode.outputs.is-quarto == 'true'
run: |
set -euo pipefail
EXT_DIR=./extensions/${{ inputs.extension-name }}

# Without a _quarto.yml the directory is not a project, so Connect renders
# only the entrypoint and no sibling Markdown becomes a page.
if ! INSPECT=$(quarto inspect "$EXT_DIR" 2>/dev/null); then

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any quarto inspect failure will result in "not a Quarto project" so if the _quarto.yml is incorrect, like missing a semicolon in render: quarto inspect will error, but this will pass.

I think that this is tricky to do right though, maybe this is a good first pass that we improve over time.

echo "Not a Quarto project; only the entrypoint renders. OK."
exit 0
fi

# Websites legitimately render many pages and serve index.html by convention.
PROJECT_TYPE=$(jq -r '.config.project.type // "default"' <<< "$INSPECT")
if [ "$PROJECT_TYPE" == "website" ]; then
echo "Website project; many pages are expected. OK."
exit 0
fi

# Rendered input basenames.
INPUTS=$(jq -r '.files.input[] | split("/") | last' <<< "$INSPECT")
COUNT=$(grep -c . <<< "$INPUTS")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there are no input matches I think this will exit 1 and fail.


# A lone document is unambiguously the served document. Otherwise a
# rendered sibling Markdown file (Quarto ignores README.md) is a stray
# page that could become the served document.
STRAY_MD=$(grep -iE '\.md$' <<< "$INPUTS" | grep -viE '^README\.md$' || true)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't checking for stray .qmd docs or other file types that Quarto can render.

if [ "$COUNT" -gt 1 ] && [ -n "$STRAY_MD" ]; then
echo "Error: Quarto extension '${{ inputs.extension-name }}' renders sibling Markdown page(s):"
echo "$STRAY_MD"
echo "Pin the entrypoint in _quarto.yml (project.render) so only it renders and becomes the served document."
exit 1
fi

echo "No stray Markdown pages render. OK."
shell: bash
1 change: 1 addition & 0 deletions .github/workflows/extensions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
_infra:
- integration/**
- .github/actions/connect-integration-test/**
- .github/actions/lint-extension/**

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be added to the complex-extension block too?

- .github/workflows/connect-integration-tests.yml
- .github/workflows/extensions.yml
quarto-stock-report-python: extensions/quarto-stock-report-python/**
Expand Down
21 changes: 21 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -442,3 +442,24 @@ to document changes made on each release.

A recommended format is the [keep a changelog](https://keepachangelog.com/en/1.1.0/)
format and ahering to the [Semantic Versioning](https://semver.org/) guidelines.

### Quarto: render only what you serve

Quarto renders every sibling Markdown file as its own page. It ignores
`README.md`, but not `CHANGELOG.md`. So a `CHANGELOG.md` in a Quarto extension
is rendered into a `CHANGELOG.html` page, and with no pinned primary the default
served document can silently flip to it instead of your entrypoint, with every
build-time check still passing.

A Quarto extension should render only the document it serves. Pin the entrypoint
in `_quarto.yml` so nothing else renders:

```yaml
project:
render:
- index.qmd # or your real entrypoint, e.g. script.py or script.R
```

Websites are the exception: they render many pages and serve `index.html` by
convention. Linting fails any non-website extension that renders a sibling
Markdown page like a `CHANGELOG`.
6 changes: 6 additions & 0 deletions extensions/pqr/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to the Quarto Document with Python and R extension will be d
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.4] - 2026-07-24

### Changed

- Added a `_quarto.yml` pinning `project.render` to `index.qmd` so only the document renders, preventing a sibling `CHANGELOG.md` from rendering as a stray page. (#442)

## [0.1.3] - 2026-06-22

### Fixed
Expand Down
6 changes: 6 additions & 0 deletions extensions/pqr/_quarto.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
project:
# Render only the document so it is the unambiguous primary document.
# Without this, Quarto also renders sibling Markdown (e.g. CHANGELOG.md)
# and the default served document can become that file instead.
render:
- index.qmd
5 changes: 4 additions & 1 deletion extensions/pqr/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,9 @@
".Rprofile": {
"checksum": "57f9047cb06fdbef821b61f49e21406e"
},
"_quarto.yml": {
"checksum": "6087acf57476d9f95b353c3db3ae0fb2"
},
"index.qmd": {
"checksum": "e3c9e1907f7e77e8d7da0492e92d9def"
},
Expand All @@ -1289,6 +1292,6 @@
"category": "example",
"tags": ["python", "quarto", "r"],
"minimumConnectVersion": "2025.04.0",
"version": "0.1.3"
"version": "0.1.4"
}
}
8 changes: 0 additions & 8 deletions extensions/quarto-document/connect-extension.qmd

This file was deleted.

7 changes: 7 additions & 0 deletions extensions/quarto-stock-report-python/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to the Quarto Stock Report using Python extension will be do
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.6] - 2026-07-24

### Changed

- Pinned the Quarto `project.render` list to `index.qmd` so only the report renders, preventing a sibling `CHANGELOG.md` from rendering as a stray page. (#442)
- Removed `connect-extension.qmd`, a superseded legacy gallery-metadata file that is no longer used. (#442)

## [1.0.5] - 2026-06-15

### Changed
Expand Down
5 changes: 5 additions & 0 deletions extensions/quarto-stock-report-python/_quarto.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
project:
title: Stock Report
# Render only the report so it is the unambiguous primary document.
# Without this, Quarto also renders sibling Markdown (e.g. CHANGELOG.md)
# and the default served document can become that file instead.
render:
- index.qmd
8 changes: 0 additions & 8 deletions extensions/quarto-stock-report-python/connect-extension.qmd

This file was deleted.

4 changes: 2 additions & 2 deletions extensions/quarto-stock-report-python/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"minimumConnectVersion": "2025.04.0",
"category": "example",
"tags": ["quarto", "python"],
"version": "1.0.5"
"version": "1.0.6"
},
"environment": {
"python": {
Expand All @@ -38,7 +38,7 @@
},
"files": {
"_quarto.yml": {
"checksum": "35b4c4c58cce875b126683c525ad40f4"
"checksum": "c18e19d86e99c788e4ccfabf68179aa2"
},
"index.qmd": {
"checksum": "7eeaeddb32075ffea02ef77ada5b719b"
Expand Down
6 changes: 6 additions & 0 deletions extensions/quarto-stock-report-r/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to the Quarto Stock Report using R extension will be documen
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.5] - 2026-07-24

### Changed

- Pinned the Quarto `project.render` list to `index.qmd` so only the report renders, preventing a sibling `CHANGELOG.md` from rendering as a stray page. (#442)

## [1.0.4] - 2026-06-11

### Changed
Expand Down
5 changes: 5 additions & 0 deletions extensions/quarto-stock-report-r/_quarto.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
project:
title: Stock Report
# Render only the report so it is the unambiguous primary document.
# Without this, Quarto also renders sibling Markdown (e.g. CHANGELOG.md)
# and the default served document can become that file instead.
render:
- index.qmd
6 changes: 3 additions & 3 deletions extensions/quarto-stock-report-r/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"category": "example",
"minimumConnectVersion": "2025.04.0",
"tags": ["quarto", "r"],
"version": "1.0.4"
"version": "1.0.5"
},
"packages": {
"DT": {
Expand Down Expand Up @@ -2419,13 +2419,13 @@
},
"files": {
"_quarto.yml": {
"checksum": "35b4c4c58cce875b126683c525ad40f4"
"checksum": "c18e19d86e99c788e4ccfabf68179aa2"
},
".output_metadata.json": {
"checksum": "a335b9151c7b39bed18fd0f56928ce68"
},
"CHANGELOG.md": {
"checksum": "6adb848a545277816a79a36437af87db"
"checksum": "659505e735500a6cdd3480f30d401d8d"
},
"data.csv": {
"checksum": "d64607673ef065841a9d355317ec8d7b"
Expand Down
Loading