Skip to content
Merged
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
111 changes: 111 additions & 0 deletions .github/hurl-examples.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Shared changes run every examples/*/test.hurl, including newly added examples.
all_examples:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include built-in templates in the shared-change filter

The all_examples filter omits sqlpage/**, so a PR that changes only a built-in Handlebars component produces [] and skips every Hurl suite. These templates are embedded into the binary and consumed throughout the examples—for instance, the cards and forms suites assert their rendered HTML—so template regressions that appear only in complete example flows will no longer be exercised; add sqlpage/** (or at least sqlpage/templates/**) to this filter.

AGENTS.md reference: AGENTS.md:L36-L42

Useful? React with 👍 / 👎.

- 'examples/**'
- 'Dockerfile'
- '.dockerignore'
- 'Cargo.toml'
- 'Cargo.lock'
- 'build.rs'
- '.cargo/**'
- 'scripts/**'
- '.github/workflows/ci.yml'
- '.github/hurl-examples.yml'

# Keys are example folders; add one glob per line to associate more files.
# Keep suites with distinctive integration coverage; describe it above each entry.
Comment on lines +14 to +15

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Map the custom-component Hurl suite

When a PR changes src/templates.rs, src/dynamic_component.rs, or src/webserver/database/sqlpage_functions/functions/run_sql.rs, none of these filters match, so the selector emits [] and skips Hurl. examples/custom form component/index.sql combines a sqlpage.run_sql-driven dynamic row with a custom dual-list Handlebars template, and its test.hurl verifies the rendered and submitted flow, so this distinctive integration suite should be mapped to those runtime paths.

AGENTS.md reference: AGENTS.md:L36-L42

Useful? React with 👍 / 👎.


# Trace propagation through nginx and actual OTLP export into Tempo.
'examples/telemetry':
- 'src/telemetry.rs'
- 'src/app_config.rs'
- 'src/main.rs'
- 'src/webserver/http.rs'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Treat the shared HTTP server as an all-example dependency

A change to src/webserver/http.rs now selects only examples/telemetry, although this module builds the request pipeline used by every suite and wires routing, static assets, uploads, and OIDC middleware. For example, a change that breaks multipart limits or OIDC middleware ordering can pass the telemetry test while the upload and single-sign-on suites are skipped; move this path to all_examples or associate every dependent suite.

AGENTS.md reference: AGENTS.md:L49-L54

Useful? React with 👍 / 👎.

- 'src/webserver/http_client.rs'
- 'src/webserver/database/execute_queries.rs'

# Mailpit checks delivered MIME parts; the form asserts delayed multipart encoding.
'examples/sending emails':
- 'src/app_config.rs'
- 'src/webserver/http_request_info.rs'
- 'src/webserver/database/sqlpage_functions/functions/send_mail.rs'
- 'src/webserver/database/sqlpage_functions/functions/uploaded_file_name.rs'
- 'src/webserver/database/sqlpage_functions/functions/uploaded_file_path.rs'
- 'src/webserver/database/sqlpage_functions/functions/read_file_as_data_url.rs'
Comment on lines +30 to +33

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Select the mail suite for data-URL codec changes

When src/webserver/database/blob_to_data_url.rs changes, no filter selects the sending-email suite even though both read_file_as_data_url and send_mail call this module to encode and decode attachments. The suite uploads an attachment and verifies its filename, MIME type, and contents through Mailpit, so this path should be included here to prevent an attachment codec regression from skipping its only end-to-end coverage.

AGENTS.md reference: AGENTS.md:L25-L29

Useful? React with 👍 / 👎.

- 'sqlpage/templates/form.handlebars'

# Real Keycloak discovery, login, callback cookies, and identity claims in SQL.
'examples/single sign on':
- 'src/app_config.rs'
- 'src/lib.rs'
- 'src/webserver/oidc.rs'
- 'src/webserver/http.rs'
- 'src/webserver/routing.rs'
- 'src/webserver/http_client.rs'
- 'src/webserver/http_request_info.rs'
- 'src/webserver/database/sqlpage_functions/functions/user_info*.rs'
- 'src/webserver/database/sqlpage_functions/functions/oidc_logout_url.rs'

# A real proxy connects to SQLPage's Unix socket and rewrites pretty URLs.
'examples/nginx':
- 'src/app_config.rs'
- 'src/main.rs'
- 'src/webserver/http.rs'
- 'src/webserver/routing.rs'

# Apache proxies a site prefix, including the missing trailing slash redirect.
'examples/web servers - apache':
- 'src/app_config.rs'
- 'src/webserver/http.rs'
- 'src/webserver/routing.rs'

# Load SpatiaLite's native library and use its spatial functions on pooled SQLite.
'examples/make a geographic data application using sqlite extensions':
- 'src/app_config.rs'
- 'src/webserver/database/connect.rs'

# Create a PostgreSQL-backed page, request it, and render dynamic rows in a table.
'examples/SQLPage developer user interface':
- 'src/filesystem.rs'
- 'src/file_cache.rs'
- 'src/webserver/routing.rs'
- 'src/webserver/database/sqlpage_functions/functions/link.rs'
- 'sqlpage/templates/table.handlebars'

# Posted arrays feed MySQL JSON_TABLE; native JSON builds the select options.
'examples/mysql json handling':
- 'src/webserver/http_request_info.rs'
- 'src/webserver/request_variables.rs'
- 'src/webserver/single_or_vec.rs'
Comment on lines +76 to +78

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Select a variables suite for the variables function

A change confined to src/webserver/database/sqlpage_functions/functions/variables.rs does not match this entry or any other filter, despite being the implementation of sqlpage.variables(). The variable-number form suite posts fields whose names are product IDs, consumes sqlpage.variables('post') in order_insert.sql, and verifies the resulting quantities and total, so that suite should be selected for changes to the function itself.

AGENTS.md reference: AGENTS.md:L19-L24

Useful? React with 👍 / 👎.

- 'src/webserver/database/sql.rs'
- 'src/webserver/database/sql/**'
- 'src/webserver/database/execute_queries.rs'
- 'src/webserver/database/sql_to_json.rs'
- 'sqlpage/templates/form.handlebars'

# A real cookie jar round-trips an encoded space and removes it from a subfolder.
'examples/read-and-set-http-cookies':
- 'src/render.rs'
- 'src/webserver/http_request_info.rs'
- 'src/webserver/database/sqlpage_functions/functions/cookie.rs'
Comment on lines +85 to +89

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Select the theme suite for header-function changes

When src/webserver/database/sqlpage_functions/functions/header.rs changes, none of the filters match and Hurl is skipped. The light/dark-toggle suite sends different Referer headers to toggle.sql, which obtains them through sqlpage.header('referer'), and asserts the resulting redirect locations, so mapping that function to this suite preserves its direct end-to-end coverage of request-header access.

AGENTS.md reference: AGENTS.md:L25-L29

Useful? React with 👍 / 👎.


# Hash a new signup's password, authenticate it, and invalidate its login session.
'examples/user-authentication':
- 'src/render.rs'
- 'src/webserver/http_request_info.rs'
- 'src/webserver/database/sqlpage_functions/functions/hash_password.rs'
- 'src/webserver/database/sqlpage_functions/functions/random_string.rs'
- 'src/webserver/database/sqlpage_functions/functions/cookie.rs'

# Authenticated multipart upload persists an image into a writable container mount.
'examples/image gallery with user uploads':
- 'src/app_config.rs'
- 'src/webserver/http_request_info.rs'
- 'src/webserver/database/sqlpage_functions/functions/persist_uploaded_file.rs'
- 'src/webserver/database/sqlpage_functions/functions/uploaded_file_mime_type.rs'
- 'src/webserver/database/sqlpage_functions/functions/random_string.rs'

# JSON menus with icon-only submenus and arrays of custom scripts/styles.
'examples/CRUD - Authentication': ['sqlpage/templates/shell.handlebars']

# Cards combine Markdown and remote chart/map/table embed markup.
'examples/cards-with-remote-content': ['sqlpage/templates/card.handlebars']
Comment on lines +110 to +111

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Select the quiz suite for file-reader changes

When src/webserver/database/sqlpage_functions/functions/read_file_as_text.rs changes, the selector currently emits []. The multiple-choice-question pages exercised by Hurl load website_header.json through sqlpage.read_file_as_text before rendering both the quiz and its results, so mapping this function to that suite would retain end-to-end coverage of file-backed component properties.

AGENTS.md reference: AGENTS.md:L25-L29

Useful? React with 👍 / 👎.

30 changes: 26 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -333,22 +333,42 @@ jobs:
retention-days: 1
hurl_examples:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
env:
DIFF_BASE: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }}
outputs:
examples: ${{ steps.examples.outputs.examples }}
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- id: paths
name: Match changed paths to Hurl suites
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
if: ${{ github.ref_type != 'tag' && env.DIFF_BASE != '' && !startsWith(env.DIFF_BASE, '0000000') }}
continue-on-error: true
with:
base: ${{ env.DIFF_BASE }}
ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }}
filters: .github/hurl-examples.yml
- id: examples
run: |
examples="$(find examples -mindepth 2 -maxdepth 2 -name test.hurl -print | sed 's#/test.hurl$##' | sort | jq -R -s -c 'split("\n")[:-1]')"
echo "examples=$examples" >> "$GITHUB_OUTPUT"
name: Select relevant Hurl examples
run: scripts/select-hurl-examples.sh
env:
PATHS_OUTCOME: ${{ steps.paths.outcome }}
ALL_EXAMPLES: ${{ steps.paths.outputs.all_examples }}
MATCHED_EXAMPLES: ${{ steps.paths.outputs.changes }}
- name: Restore Hurl archive
id: hurl-cache
if: steps.examples.outputs.examples != '[]'
uses: actions/cache@v6
with:
path: .cache/hurl
key: hurl-${{ runner.os }}-x86_64-unknown-linux-gnu-${{ env.HURL_VERSION }}
- name: Download Hurl archive
if: steps.hurl-cache.outputs.cache-hit != 'true'
if: steps.examples.outputs.examples != '[]' && steps.hurl-cache.outputs.cache-hit != 'true'
run: |
set -euo pipefail
archive="hurl-${HURL_VERSION}-x86_64-unknown-linux-gnu.tar.gz"
Expand All @@ -363,6 +383,7 @@ jobs:
test "$expected_sha" = "$actual_sha"
)
- name: Upload Hurl archive
if: steps.examples.outputs.examples != '[]'
uses: actions/upload-artifact@v7
with:
name: hurl-${{ env.HURL_VERSION }}-x86_64-unknown-linux-gnu
Expand All @@ -373,6 +394,7 @@ jobs:
hurl:
name: hurl (${{ matrix.example }})
runs-on: ubuntu-latest
if: ${{ needs.hurl_examples.outputs.examples != '[]' }}
timeout-minutes: 15
needs:
- docker_build
Expand Down
13 changes: 13 additions & 0 deletions scripts/select-hurl-examples.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -euo pipefail

if [[ "${PATHS_OUTCOME:-}" == success && "${ALL_EXAMPLES:-}" != true ]]; then
examples="$MATCHED_EXAMPLES"
else
# Tags, missing diff bases, and failed path filtering run every example.
examples="$(find examples -mindepth 2 -maxdepth 2 -name test.hurl -print \
| sed 's#/test.hurl$##' | sort | jq -R -s -c 'split("\n")[:-1]')"
fi

echo "examples=$examples" >> "$GITHUB_OUTPUT"
echo "Selected Hurl examples: $examples" >> "$GITHUB_STEP_SUMMARY"
Loading