diff --git a/.github/workflows/halo.yaml b/.github/workflows/halo.yaml index 2813bf1e7..e260f415e 100644 --- a/.github/workflows/halo.yaml +++ b/.github/workflows/halo.yaml @@ -67,6 +67,7 @@ jobs: steps: - uses: actions/checkout@v3 - uses: halo-sigs/actions/halo-next-docker-build@main # change the version to specific ref or release tag while the action is stable. + if: github.event_name != 'pull_request' with: image-name: ${{ github.event_name == 'release' && 'halo' || 'halo-dev' }} ghcr-token: ${{ secrets.GHCR_TOKEN }} @@ -74,3 +75,18 @@ jobs: dockerhub-token: ${{ secrets.DOCKER_TOKEN }} push: ${{ github.event_name == 'push' || github.event_name == 'release' }} # we only push to GHCR if the push is to the next branch console-ref: ${{ github.event_name == 'release' && github.ref || 'main' }} + - uses: halo-sigs/actions/halo-next-docker-build@main + if: github.event_name == 'pull_request' + with: + image-name: halo-dev + push: false + console-ref: false + load: true + platforms: "" + - name: test + run: | + sudo curl -L https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose + sudo chmod u+x /usr/local/bin/docker-compose + + docker tag ghcr.io/halo-dev/halo-dev:pr-${{ github.event.number }} ghcr.io/halo-dev/halo-dev:dev + cd e2e && ./start.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bb827c9c6..dfe0cf7ef 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,6 +48,10 @@ git pull upstream master git push ``` +### E2E + +Please consider adding some [e2e test cases](e2e/README.md) to make sure the APIs work as expected. + ### 开发规范 请参考 [https://docs.halo.run/developer-guide/core/code-style](https://docs.halo.run/developer-guide/core/code-style),请确保所有代码格式化之后再提交。 diff --git a/e2e/Dockerfile b/e2e/Dockerfile new file mode 100644 index 000000000..95fa5de25 --- /dev/null +++ b/e2e/Dockerfile @@ -0,0 +1,4 @@ +FROM linuxsuren/api-testing:v0.0.14 +WORKDIR /workspace +COPY testsuite.yaml . +CMD [ "atest", "run", "-p", "testsuite.yaml", "--level=debug" ] diff --git a/e2e/README.md b/e2e/README.md new file mode 100644 index 000000000..6a1906111 --- /dev/null +++ b/e2e/README.md @@ -0,0 +1,17 @@ +Please add the corresponding e2e (aka end-to-end) test cases if you add or update APIs. + +## How to work +* Start and watch the [docker-compose](https://docs.docker.com/compose/) via [the script](start.sh) + * It has three containers: database, Halo, and testing +* Run the e2e testing via [api-testing](https://github.com/LinuxSuRen/api-testing) + * It will run the test cases from top to bottom + * You can add the necessary asserts to it + +## Run locally +Please follow these steps if you want to run the e2e testing locally. + +> Please make sure you have installed docker-compose v2 + +* Build project via `./gradlew clean build -x check` in root directory of this repository +* Build image via `docker build . -t ghcr.io/halo-dev/halo-dev:dev` +* Change the directory to `e2e`, then execute `./start.sh` diff --git a/e2e/compose.yaml b/e2e/compose.yaml new file mode 100644 index 000000000..74e703d88 --- /dev/null +++ b/e2e/compose.yaml @@ -0,0 +1,48 @@ +version: '3.1' +services: + testing: + build: + context: . + dockerfile: Dockerfile + links: + - halo + depends_on: + halo: + condition: service_healthy + halo: + image: ghcr.io/halo-dev/halo-dev:dev + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8090/actuator/health/readiness"] + interval: 30s + timeout: 5s + retries: 5 + start_period: 30s + command: + - --spring.r2dbc.url=r2dbc:pool:postgresql://halodb/halo + - --spring.r2dbc.username=halo + # PostgreSQL 的密码,请保证与下方 POSTGRES_PASSWORD 的变量值一致。 + - --spring.r2dbc.password=openpostgresql + - --spring.sql.init.platform=postgresql + # 外部访问地址,请根据实际需要修改 + # - --halo.external-url=http://localhost:8090/ + links: + - postgresql + depends_on: + postgresql: + condition: service_healthy + postgresql: + image: postgres:15.4 + container_name: halodb + restart: on-failure:3 + ports: + - "5432:5432" + healthcheck: + test: [ "CMD", "pg_isready" ] + interval: 10s + timeout: 5s + retries: 5 + environment: + - POSTGRES_PASSWORD=openpostgresql + - POSTGRES_USER=halo + - POSTGRES_DB=halo + - PGUSER=halo diff --git a/e2e/start.sh b/e2e/start.sh new file mode 100755 index 000000000..0df1b0592 --- /dev/null +++ b/e2e/start.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +file=$1 +if [ "$file" == "" ] +then + file=compose.yaml +fi + +docker-compose version +docker-compose -f "$file" up --build -d + +while true +do + docker-compose -f "$file" ps | grep testing + if [ $? -eq 1 ] + then + code=-1 + docker-compose -f "$file" logs | grep e2e-testing + docker-compose -f "$file" logs | grep e2e-testing | grep Usage + if [ $? -eq 1 ] + then + code=0 + echo "successed" + fi + + docker-compose -f "$file" down + set -e + exit $code + fi + sleep 1 +done diff --git a/e2e/testsuite.yaml b/e2e/testsuite.yaml new file mode 100644 index 000000000..1776b5e32 --- /dev/null +++ b/e2e/testsuite.yaml @@ -0,0 +1,86 @@ +name: halo +api: | + {{default "http://halo:8090" (env "SERVER")}}/apis +param: + postName: "{{randAlpha 6}}" +items: +- name: init + request: + api: /api.console.halo.run/v1alpha1/system/initialize + method: POST + header: + Content-Type: application/json + body: | + { + "siteTitle": "testing", + "username": "admin", + "password": "123456", + "email": "testing@halo.com", + "password_confirm": "123456" + } + expect: + statusCode: 201 +- name: createPost + request: + api: /api.console.halo.run/v1alpha1/posts + method: POST + header: + Authorization: "Basic YWRtaW46MTIzNDU2" + Content-Type: application/json + body: | + { + "post": { + "spec": { + "title": "{{.param.postName}}", + "slug": "{{.param.postName}}", + "template": "", + "cover": "", + "deleted": false, + "publish": false, + "pinned": false, + "allowComment": true, + "visible": "PUBLIC", + "priority": 0, + "excerpt": { + "autoGenerate": true, + "raw": "" + }, + "categories": [], + "tags": [], + "htmlMetas": [] + }, + "apiVersion": "content.halo.run/v1alpha1", + "kind": "Post", + "metadata": { + "name": "c31f2192-c992-47b9-86b4-f3fc0605360e", + "annotations": { + "content.halo.run/preferred-editor": "default" + } + } + }, + "content": { + "raw": "

{{.param.postName}}

", + "content": "

{{.param.postName}}

", + "rawType": "HTML" + } + } +- name: listPosts + request: + api: /api.console.halo.run/v1alpha1/posts?keyword={{.param.postName}} + header: + Authorization: "Basic YWRtaW46MTIzNDU2" + expect: + verify: + - data.total == 1 +- name: recyclePost + request: + api: /api.console.halo.run/v1alpha1/posts/{{(index .listPosts.items 0).post.metadata.name}}/recycle + method: PUT + header: + Authorization: "Basic YWRtaW46MTIzNDU2" +- name: recover + request: + api: /content.halo.run/v1alpha1/posts/{{(index .listPosts.items 0).post.metadata.name}} + method: DELETE + header: + Authorization: "Basic YWRtaW46MTIzNDU2"