|
| 1 | +# GitHub Actions Workflow Documentation: `go-test.yml` |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +This document provides a detailed explanation of the `go-test.yml` GitHub Actions workflow. Its primary purpose is to automate the testing of the Go-based callback handler application (`go/callback/`) in conjunction with the main `docker-backup.sh` script. |
| 6 | + |
| 7 | +The workflow ensures that when the callback handler receives a correctly signed POST request (simulating an external system's callback), it can successfully execute the `docker-backup.sh` script with the provided arguments and that the backup process completes as expected. |
| 8 | + |
| 9 | +## Workflow Trigger (`on`) |
| 10 | + |
| 11 | +This workflow is triggered by: |
| 12 | + |
| 13 | +- **`push`**: Any push to the `main` or `go-callback` branches. |
| 14 | +- **`pull_request`**: Any pull request targeting the `main` or `go-callback` branches. |
| 15 | + |
| 16 | +This ensures that changes to the Go application or the workflow itself are automatically tested. |
| 17 | + |
| 18 | +## Job: `build-and-test` (`jobs.build-and-test`) |
| 19 | + |
| 20 | +This is the sole job defined in the workflow. It runs on the `ubuntu-latest` runner environment. |
| 21 | + |
| 22 | +### Steps |
| 23 | + |
| 24 | +1. **Checkout Code (`actions/checkout@v4`)** |
| 25 | + |
| 26 | + - Retrieves the repository code to the runner's workspace. |
| 27 | + |
| 28 | +2. **Set up Go (`actions/setup-go@v5`)** |
| 29 | + |
| 30 | + - Installs Go version 1.22 on the runner. |
| 31 | + |
| 32 | +3. **Cache Go Modules and Build (`actions/cache@v4`)** |
| 33 | + |
| 34 | + - Caches the Go module download directory (`~/go/pkg/mod`) and the Go build cache (`~/.cache/go-build`) to speed up subsequent workflow runs. |
| 35 | + |
| 36 | +4. **Install Dependencies (`go mod download`)** |
| 37 | + |
| 38 | + - Downloads the Go module dependencies specified in `go.mod`. |
| 39 | + |
| 40 | +5. **Build Application (`go build`)** |
| 41 | + |
| 42 | + - Compiles the Go application located in `go/callback/` into a single executable named `myapp` in the project root directory. |
| 43 | + |
| 44 | +6. **Create Test Files** |
| 45 | + |
| 46 | + - Dynamically generates two essential files for the test: |
| 47 | + - `backup.conf`: A configuration file for the Go application and `docker-backup.sh`. |
| 48 | + - `port=8080`: Configures the Go application to listen on port 8080. |
| 49 | + - `callback_secret=my-test-secret`: Sets the secret used to verify the signature of incoming callbacks. |
| 50 | + - `scriptpath=./docker-backup.sh`: Instructs the Go application to execute `./docker-backup.sh` when a valid callback is received. |
| 51 | + - This step no longer creates a mock `test-script.sh` as the workflow now uses the actual `docker-backup.sh`. |
| 52 | + |
| 53 | +7. **Run Integration Test** |
| 54 | + |
| 55 | + - This is the core testing logic: |
| 56 | + a. **Start Test Container**: Runs `docker run -d --name test-container nginx:alpine` to launch a simple Nginx container. This provides a real target for the `docker-backup.sh` script to back up. |
| 57 | + b. **Start Application**: Launches the compiled `myapp` in the background (`nohup ... &`), redirecting its logs to `app.log`. |
| 58 | + c. **Health Check**: Polls `http://localhost:8080` for up to 30 seconds to ensure the Go application has started and is ready to receive requests. |
| 59 | + d. **Prepare & Send Callback**: |
| 60 | + _ Constructs a SHA256 HMAC signature for the JSON payload `{"args":["test-container"]}` using the secret `my-test-secret`. |
| 61 | + _ Sends a `POST` request to `http://localhost:8080/backup` with: |
| 62 | + _ `Content-Type: application/json` |
| 63 | + _ `X-Signature: sha256=<calculated_signature>` |
| 64 | + _ Request Body: `{"args":["test-container"]}` |
| 65 | + _ This simulates an external system invoking the callback endpoint. |
| 66 | + e. **Verify Application Response**: |
| 67 | + _ Checks that the HTTP status code returned by the application is `200 OK`. |
| 68 | + _ Checks that the response body contains the string `"Backup initiated successfully"`. \* If either check fails, the workflow outputs the application logs (`app.log`) and the test container logs for debugging and then exits with an error. |
| 69 | + f. **Cleanup**: Attempts to terminate the `myapp` process and forcefully removes the `test-container`. |
| 70 | + |
| 71 | +8. **Output Application Logs (`if: always()`)** |
| 72 | + |
| 73 | + - Regardless of whether the previous steps succeeded or failed, this step prints the contents of `app.log`. This is invaluable for debugging any issues that occurred during the application's execution. |
| 74 | + |
| 75 | +9. **List Backup Artifacts (`if: always()`)** |
| 76 | + - Regardless of the test outcome, this step inspects the default backup output directory (`/tmp/docker-backups/`). |
| 77 | + - It lists the directory itself and, if any backup directories exist within it, lists the contents of each backup directory. |
| 78 | + - This verifies that `docker-backup.sh` was indeed executed by the Go application and produced the expected output structure. |
| 79 | + |
| 80 | +## Interaction with `go/callback` Application |
| 81 | + |
| 82 | +- The workflow builds and configures the application in `go/callback/`. |
| 83 | +- It relies on the application's ability to: |
| 84 | + 1. Read its configuration from `backup.conf`. |
| 85 | + 2. Listen for `POST` requests on `/backup`. |
| 86 | + 3. Validate the `X-Signature` header against the request body using the `callback_secret`. |
| 87 | + 4. Parse the JSON body to extract the `args` array. |
| 88 | + 5. Execute the script specified by `scriptpath` (`./docker-backup.sh`) with the extracted `args` (e.g., `["test-container"]`). |
| 89 | + 6. Return a `200 OK` status with a success message upon initiating the script. |
| 90 | + |
| 91 | +## Interaction with `docker-backup.sh` |
| 92 | + |
| 93 | +- The workflow configures the `go/callback` application to execute `docker-backup.sh`. |
| 94 | +- It provides a real Docker container (`test-container`) as an argument to `docker-backup.sh`. |
| 95 | +- It verifies that `docker-backup.sh` creates its backup output in `/tmp/docker-backups/` by listing the directory contents. |
0 commit comments