Skip to content

Commit 6218bfa

Browse files
Merge pull request #95 from ricardogsilva/94-add-workflow-for-integration-tests
Add a workflow for testing github action
2 parents 2ef2e34 + 6621125 commit 6218bfa

File tree

8 files changed

+560
-54
lines changed

8 files changed

+560
-54
lines changed

.github/workflows/test-action.yaml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Test cite-runner as a GitHub action
2+
3+
on:
4+
# will run both when pushing a branch and when pushing a tag
5+
push:
6+
7+
pull_request:
8+
9+
# will run when called from another workflow
10+
workflow_call:
11+
12+
env:
13+
COLUMNS: 120
14+
15+
jobs:
16+
test_cite_runner_github_action:
17+
runs-on: ubuntu-24.04
18+
env:
19+
SIMPLESERVER_PORT: 9092
20+
steps:
21+
- name: "Grab code"
22+
uses: actions/checkout@v4.2.2
23+
- name: "Set up Python"
24+
uses: actions/setup-python@v5
25+
with:
26+
python-version-file: "pyproject.toml"
27+
- name: "Launch simple test server"
28+
run: |
29+
nohup python tests/simpleserver.py --bind-address 0.0.0.0 --bind-port ${{ env.SIMPLESERVER_PORT }} > /dev/null 2>&1 &
30+
echo $! > simpleserver.pid
31+
sleep 1
32+
if ps --pid $(cat simpleserver.pid) > /dev/null; then
33+
echo "simpleserver is up and running with PID $(cat simpleserver.pid)"
34+
else
35+
echo "simpleserver failed to start"
36+
exit 1
37+
fi
38+
- name: "Test cite-runner GitHub action"
39+
id: test_cite_runner_github_action
40+
uses: ./
41+
with:
42+
test_suite_identifier: ogcapi-features-1.0
43+
test_session_arguments: iut=http://host.docker.internal:${{ env.SIMPLESERVER_PORT }}
44+
exit_with_error: "false"
45+
- name: "Verify cite-runner results"
46+
run: |
47+
jq '.' <<EOF | python tests/github_action_tests.py -
48+
${{ steps.test_cite_runner_github_action.outputs.json_report }}
49+
EOF
50+
- name: "Shut down simple test server"
51+
if: always()
52+
run: |
53+
if [ -f server.pid ]; then
54+
echo "Shutting down simpleserver with PID $(cat simpleserver.pid)..."
55+
kill $(cat simpleserver.pid) || true
56+
rm simpleserver.pid
57+
fi

action.yml

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,29 +50,36 @@ inputs:
5050
description: Whether the action exits with an error if the test suite execution shows a result of failed.
5151

5252
outputs:
53-
results:
54-
description: "Test results"
55-
value: '${{ steps.run_cite_runner.outputs.MARKDOWN_RESULT_OUTPUT_PATH }}'
53+
json_report:
54+
description: "Full test suite execution result as JSON"
55+
value: '${{ steps.run_cite_runner.outputs.JSON_REPORT }}'
5656

5757
runs:
5858
using: 'composite'
5959
steps:
6060
- name: "Add action path to the global path"
6161
shell: bash
6262
run: echo "${{ github.action_path }}" >> ${GITHUB_PATH}
63+
- name: "normalize action path"
64+
id: normalize_action_path
65+
shell: "bash"
66+
run: |
67+
echo "ACTION_NORMALIZED_PATH=$(realpath -m ${{ github.action_path }})" >> "${GITHUB_OUTPUT}"
6368
- name: "Install uv"
6469
uses: astral-sh/setup-uv@v5
6570
with:
6671
version: "0.6.13"
6772
enable-cache: true
68-
cache-dependency-glob: "${{ github.action_path }}/uv.lock"
73+
cache-dependency-glob: "${{ steps.normalize_action_path.outputs.ACTION_NORMALIZED_PATH }}/uv.lock"
6974
- name: "Set up Python"
7075
uses: actions/setup-python@v5
7176
with:
7277
python-version-file: "${{ github.action_path }}/pyproject.toml"
7378
- name: "Install cite-runner"
7479
env:
75-
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_CITE_RUNNER: ${{ github.action_ref }}
80+
# GITHUB_CONTEXT: ${{ toJSON(github) }}
81+
# ENV_CONTEXT: ${{ toJSON(env) }}
82+
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_CITE_RUNNER: ${{ env.GITHUB_ACTION_REF }}
7683
shell: "bash"
7784
run: |
7885
cd ${{ github.action_path }}
@@ -85,7 +92,8 @@ runs:
8592
--detach
8693
--rm
8794
--name teamengine
88-
--network host
95+
--add-host=host.docker.internal:host-gateway
96+
--publish 9080:8080
8997
ogccite/teamengine-production:1.0-SNAPSHOT
9098
- name: "Run cite-runner"
9199
id: "run_cite_runner"
@@ -96,13 +104,17 @@ runs:
96104
uv run cite-runner \
97105
--network-timeout=${{ inputs.network_timeout_seconds }} \
98106
execute-test-suite-from-github-actions \
99-
${{ inputs.teamengine_url || 'http://localhost:8080/teamengine' }} \
107+
${{ inputs.teamengine_url || 'http://localhost:9080/teamengine' }} \
100108
${{ inputs.test_suite_identifier }} \
101109
--output-format=raw \
102110
--teamengine-username=${{ inputs.teamengine_username }} \
103111
--teamengine-password=${{ inputs.teamengine_password }} \
104112
$(echo -e ${{ inputs.test_session_arguments }}) 1> ${RAW_PATH}
105-
echo "RAW_RESULT_OUTPUT_PATH=${{ github.action_path }}/${RAW_PATH}" >> "${GITHUB_OUTPUT}"
113+
if [ $? -ne 0 ]; then
114+
echo "Unable to use TeamEngine to execute test suite ${{ inputs.test_suite_identifier }} with arguments ${{ inputs.test_session_arguments }}"
115+
exit 1
116+
fi
117+
echo "RAW_RESULT_OUTPUT_PATH=${{ steps.normalize_action_path.outputs.ACTION_NORMALIZED_PATH }}/${RAW_PATH}" >> "${GITHUB_OUTPUT}"
106118
echo "::group::cite-runner suite execution results"
107119
uv run cite-runner parse-result \
108120
--output-format console \
@@ -123,17 +135,20 @@ runs:
123135
${{ fromJSON(inputs.with_passed) && '--with-passed \' || '--without-passed \'}}
124136
${RAW_PATH} 1> ${MARKDOWN_PATH}
125137
cat ${MARKDOWN_PATH} >> ${GITHUB_STEP_SUMMARY}
126-
echo "MARKDOWN_RESULT_OUTPUT_PATH=${{ github.action_path }}/${MARKDOWN_PATH}" >> "${GITHUB_OUTPUT}"
138+
echo "MARKDOWN_RESULT_OUTPUT_PATH=${{ steps.normalize_action_path.outputs.ACTION_NORMALIZED_PATH }}/${MARKDOWN_PATH}" >> "${GITHUB_OUTPUT}"
139+
echo "JSON_REPORT=$(uv run cite-runner parse-result \
140+
--output-format json \
141+
${RAW_PATH}
142+
)" >> "${GITHUB_OUTPUT}"
127143
- name: "Store execution results as artifacts"
128-
if: ${{ !cancelled() }}
129144
uses: actions/upload-artifact@v4
130145
with:
131146
name: 'execution-results-${{ inputs.test_suite_identifier }}'
132147
path: |
133148
${{ steps.run_cite_runner.outputs.RAW_RESULT_OUTPUT_PATH }}
134149
${{ steps.run_cite_runner.outputs.MARKDOWN_RESULT_OUTPUT_PATH }}
135-
- name: "Stop TEAM engine container"
136-
if: ${{ !cancelled() && !inputs.teamengine_url }}
150+
- name: "Stop teamengine container"
151+
if: ${{ always() && !inputs.teamengine_url }}
137152
shell: "bash"
138153
run: docker stop teamengine
139154
- name: "Set action exit code"

docs/development.md

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,31 +57,78 @@ In a brief nutshell:
5757
docker run \
5858
--rm \
5959
--name=teamengine \
60-
--network=host \
60+
--add-host=host.docker.internal:host-gateway \
61+
--publish=9080:8080 \
6162
ogccite/teamengine-production:1.0-SNAPSHOT
6263
```
6364

64-
You should now be able to use `http:localhost:8080/teamengine` in
65-
cite-runner
65+
You should now be able to use `http:localhost:9080/teamengine` as the teamengine URL in
66+
cite-runner.
6667

67-
!!! warning
68-
69-
teamengine will try to run on your local port `8080`, which could
70-
potentially already be occupied by another application.
68+
!!! note
7169

72-
7. Work on the cite-runner code
70+
Using docker's `--add-host=host.docker.internal:host-gateway` is necessary when running
71+
docker engine, as discussed in the [docker engine docs:material-open-in-new:]{: target="blank_" }. If
72+
you are using docker desktop you can omit this flag.
7373
74-
8. You can run cite-runner via uv with:
74+
7. You can run cite-runner via uv with:
7575
7676
```shell
7777
uv run cite-runner
7878
```
7979
80-
8. If you want to work on documentation, you can start the mkdocs server with:
80+
!!! warning
8181
82-
```shell
83-
uv run mkdocs serve
84-
```
82+
When using cite-runner with a local teamengine instance that is running via docker and also testing an
83+
OGC service that is running locally on the same machine, you must not use `localhost` when providing the
84+
service's URL to teamengine, but rather use `host.docker.internal`.
85+
86+
As an example:
87+
88+
```shell
89+
uv run cite-runner execute-test-suite \
90+
http://localhost:9081/teamengine \
91+
ogcapi-features-1.0 \
92+
--suite-input iut http://host.docker.internal:9082
93+
```
94+
95+
96+
### Running tests
97+
98+
Most tests can be run with:
99+
100+
```shell
101+
uv run pytest
102+
```
103+
104+
cite-runner also includes a workflow for testing itself when running as a GitHub action. This can be run locally
105+
with a tool like [act:material-open-in-new:]{: target="blank_" }.
106+
107+
```shell
108+
act \
109+
--workflows .github/workflows/test-action.yaml \
110+
--rm \
111+
--platform ubuntu-24.04=ghcr.io/catthehacker/ubuntu:act-24.04 \
112+
--container-options="-p 9092:9092" \
113+
--artifact-server-path $PWD/.artifacts
114+
```
115+
116+
The `.github/workflows/test-action.yaml` workflow launches a simple HTTP server which contains a very incomplete
117+
implementation of OGC API - Features and then uses the cite-runner GitHub action to run the `ogcapi-features-1.0`
118+
test suite on it. It then captures the cite-runner output, and runs it through some Python tests to verify the
119+
result matches what is expected.
120+
121+
122+
### Documentation
123+
124+
If you want to work on documentation, you can start the mkdocs server with:
125+
126+
```shell
127+
uv run mkdocs serve
128+
```
129+
130+
Now edit files under the `/docs` directory and check whether they match your expected result in the mkdocs dev server,
131+
which would be running at `http://localhost:8000/cite-runner/
85132
86133
87134
## Release management
@@ -100,6 +147,8 @@ set up to run whenever a new tag named `v*` is pushed to the repository. This wo
100147
101148
102149
150+
[act:material-open-in-new:]: https://nektosact.com/introduction.html
151+
[docker engine docs:material-open-in-new:]: https://docs.docker.com/reference/cli/docker/container/run/#add-host
103152
[GitHub actions workflow:material-open-in-new:]: https://github.com/OSGeo/cite-runner/blob/main/.github/workflows/release.yaml
104153
[httpx:material-open-in-new:]: https://www.python-httpx.org/
105154
[jinja:material-open-in-new:]: https://jinja.palletsprojects.com/en/stable/

docs/running-as-github-action.md

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ and specify which test suite to run, alongside any relevant parameters.
1818
Although cite-runner is not yet published in the [GitHub marketplace:material-open-in-new:]{: target="blank_" } it
1919
can still be used in GitHub CI workflows.
2020

21-
[GitHub action:material-open-in-new:]: https://docs.github.com/en/actions/sharing-automations/creating-actions/about-custom-actions
22-
[GitHub marketplace:material-open-in-new:]: https://github.com/marketplace
23-
2421
Include it as any other GitHub action, by creating a workflow step that
2522
specifies `uses: OSGEO/cite-runner` and provide execution parameters in the
2623
`with` parameter.
@@ -202,10 +199,35 @@ When run as a GitHub action, cite-runner expects the following inputs to be prov
202199

203200

204201

205-
[GitHub actions inputs:material-open-in-new:]: https://docs.github.com/en/actions/sharing-automations/creating-actions/metadata-syntax-for-github-actions#inputs
206-
[fromJSON() function:material-open-in-new:]: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/evaluate-expressions-in-workflows-and-actions#fromjson
207-
[ternary operator:material-open-in-new:]: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/evaluate-expressions-in-workflows-and-actions#operators
202+
## Outputs
208203

204+
The cite-runner GitHub Action will provide a single output, which is a full report of the test suite results:
205+
206+
207+
### json_report
208+
209+
This is a JSON document containing the full parsed test suite execution results. You can use it in further GitHub
210+
workflow steps to verify suite execution. As an example of further processing, you can pipe the result to
211+
[jq:material-open-in-new:]{: target="blank_" }, as seen below:
212+
213+
```yaml
214+
- name: "Verify cite-runner results"
215+
run: |
216+
jq '.passed' <<EOF
217+
${{ steps.test_cite_runner_github_action.outputs.json_report }}
218+
EOF
219+
```
220+
221+
!!! tip
222+
223+
Handling outputs of a GitHub Action that represent JSON data can be a bit tricky. The previous example showcases
224+
using a [HERE doc:material-open-in-new:]{: target="blank_" }, which has the benefit of preserving whatever
225+
double/single quotes may be present in the underlying JSON data. We recommend always using this technique to
226+
process cite-runner GitHub Action's output
227+
228+
229+
[cite-runner's own testing workflow:material-open-in-new:]{: target="blank_" } has an additional example of using
230+
the action's output and passing it to another command for further processing.
209231

210232
## Usage examples
211233

@@ -422,6 +444,15 @@ relevant steps consist of calling cite-runner as a standalone CLI application. B
422444
7. Finally, set the action exit code. This is done by retrieving the exit code that had been stored in 4.2 and using it
423445
to set the overall action exit code.
424446

447+
448+
[cite-runner's own testing workflow:material-open-in-new:]: https://github.com/OSGeo/cite-runner/tree/main/.github/workflows/test-action.yaml
425449
[composite action:material-open-in-new:]: https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-composite-action
426450
[custom shell:material-open-in-new:]: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell
451+
[jq:material-open-in-new:]: https://jqlang.org/
452+
[fromJSON() function:material-open-in-new:]: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/evaluate-expressions-in-workflows-and-actions#fromjson
453+
[GitHub action:material-open-in-new:]: https://docs.github.com/en/actions/sharing-automations/creating-actions/about-custom-actions
454+
[GitHub actions inputs:material-open-in-new:]: https://docs.github.com/en/actions/sharing-automations/creating-actions/metadata-syntax-for-github-actions#inputs
455+
[GitHub marketplace:material-open-in-new:]: https://github.com/marketplace
456+
[HERE doc:material-open-in-new:]: https://linuxize.com/post/bash-heredoc/
427457
[set -e:material-open-in-new:]: https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#The-Set-Builtin
458+
[ternary operator:material-open-in-new:]: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/evaluate-expressions-in-workflows-and-actions#operators

0 commit comments

Comments
 (0)