-
Notifications
You must be signed in to change notification settings - Fork 1
Add automated release workflow with health check and restart endpoints #1017
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- Created health.ts handler that reads version from package.json
- Added GET /health route to server.ts
- Created health.test.ts with TDD approach
- Added version field (0.0.0) to package.json
- Health endpoint returns JSON: {"version": "x.y.z", "status": "ok"}
Co-authored-by: drewvolz <[email protected]>
- Created auth middleware to verify Bearer token - Added POST /restart endpoint protected by auth middleware - Restart endpoint triggers process exit (to be restarted by process manager) - Updated .env.sample with RESTART_TOKEN documentation - Created comprehensive tests for both auth middleware and restart endpoint - All tests pass and manual testing confirms functionality Co-authored-by: drewvolz <[email protected]>
- Created .github/workflows/release.yml for automated releases - Workflow triggers on release published event - Uses 'release' environment with manual approval protection - Extracts version from release tag (e.g., v1.2.3 → 1.2.3) - Triggers server restart via POST /restart endpoint - Polls /health endpoint to verify deployment (120s timeout, 5s intervals) - Sends Telegram notifications on success/failure - Updated README with comprehensive deployment documentation - Documents required GitHub secrets and environment setup Co-authored-by: drewvolz <[email protected]>
- Added 'permissions: contents: read' to limit GITHUB_TOKEN scope - Follows security best practices for GitHub Actions - Fixes CodeQL security alert about missing workflow permissions Co-authored-by: drewvolz <[email protected]>
|
@copilot can you double check the version checking? Seems like we only have hardcoded 0.0.0 into the package.json yet in the workflow we're using git tags. We should probably figure out how to compare tags as the package.json version isn't normally set for this project? |
- Removed hardcoded version from package.json (reverted to original state) - Updated health endpoint to get version from multiple sources in priority order: 1. APP_VERSION environment variable 2. VERSION file in project root 3. git describe --tags (returns tag or commit hash) 4. "unknown" as fallback - Added VERSION file to .gitignore - Updated README with comprehensive deployment setup instructions - Updated tests to cover environment variable and git fallback scenarios - All 56 tests pass Co-authored-by: drewvolz <[email protected]>
You're absolutely right! I've fixed this in commit The changes:
This works with the workflow's version extraction from release tags. The README now documents three deployment options for setting the version on the server:
Manual testing confirms all three methods work correctly. |
|
@copilot it makes more sense to start keeping track of a package.json version for standardization, and have us ensure that we're able to bump that version's patch version, commit a version update (when publishing), and checking that we've bumped the version in that healthcheck in the workflow. |
- Added version field to package.json (starting at 0.1.0) - Simplified health endpoint to read version only from package.json - Updated workflow to verify release tag matches package.json version before deployment - Removed complex fallback logic (VERSION file, APP_VERSION env var, git describe) - Updated README with standardized release process using npm version - Simplified tests to only test package.json version reading - All 55 tests pass Co-authored-by: drewvolz <[email protected]>
Done in commit Changes:
The workflow will fail if the release tag doesn't match package.json, ensuring versions are always bumped before releases. |
|
@copilot Can’t accept this restart solution just yet. It has to be able to do a docker-pull because process.exit will trigger docker to restart it… but how do we get docker to pull it, too? If we are exploring options, this poke-docker.sh script that lives server-side is available. cat poke-docker.sh Otherwise podman might be a more automated solution, which can auto-pull images in the background when they update? |
- Updated restart endpoint to execute custom restart script if RESTART_SCRIPT env var is set - Script can perform docker-compose pull && down && up for image updates - Falls back to process.exit(0) if no script configured or script fails - Added scripts/poke-docker.sh.example as reference implementation - Updated .env.sample to document RESTART_SCRIPT variable - Updated README with detailed restart behavior documentation - All 55 tests pass Co-authored-by: drewvolz <[email protected]>
Implemented in commit Changes:
The restart endpoint will execute your server-side |
|
@drewvolz I don't think we'll be able to trigger the pull from within this repo. By design, actually. The only way to influence docker on the host is by mounting the docker socket into the containers. However, once you do that, the container can do anything the host user can do in Docker - pull new images, delete containers, etc. So I think we'll have to use either a third container, that we trust, or something like Podman that can do this automatically. Or tweak Kris' script to run more often, with a semaphore of some kind, and only reboot if the pull triggered. |
Overview
This PR implements an automated deployment workflow that eliminates the need to manually SSH into the server for routine restarts after releases. The workflow uses GitHub Actions to safely trigger server restarts, verify successful deployment, and send notifications.
Changes
1. Health Check Endpoint
Added a new
GET /healthendpoint that returns the current application version and status:{ "version": "1.2.3", "status": "ok" }The version is read directly from
package.json, providing a single source of truth for version tracking. This endpoint is used by the deployment workflow to verify that the server has successfully restarted with the new version.2. Restart Endpoint
Added a new
POST /restartendpoint protected by Bearer token authentication:curl -X POST \ -H "Authorization: Bearer <RESTART_TOKEN>" \ https://api.example.com/restartThe endpoint validates the token against the
RESTART_TOKENenvironment variable and triggers a restart using one of two methods:Custom Restart Script (Docker/docker-compose deployments)
RESTART_SCRIPTenvironment variable to point to a script that handles docker-compose pull and restartRESTART_SCRIPT=/home/user/poke-docker.shdocker-compose pull && docker-compose down && docker-compose up -dto pull new images and restart containersscripts/poke-docker.sh.examplefor a reference implementationProcess Exit (Default behavior)
RESTART_SCRIPTis configured, the endpoint triggersprocess.exit(0)Security Features:
RESTART_TOKENis not set3. GitHub Actions Release Workflow
Created
.github/workflows/release.ymlthat automates the deployment process:package.jsonreleaseenvironment to support manual approval requirements/restartendpoint with authentication/healthendpoint for up to 120 seconds to confirm the new version is runningRequired GitHub Secrets:
RESTART_TOKEN- Authentication token for server restartSERVER_URL- Production server base URLTELEGRAM_TOKEN- Telegram bot token for notificationsTELEGRAM_CHAT_ID- Telegram chat ID for notifications4. Documentation
Updated README with comprehensive deployment documentation covering:
npm versionto bump versions inpackage.jsonStandardized Release Process
Before creating a release:
Update the version in
package.json:npm version patch # or minor, or majorCommit the version change:
git add package.json package-lock.json git commit -m "Bump version to X.Y.Z" git pushCreate a GitHub release with a tag matching the package.json version (e.g.,
v1.2.3)The workflow will verify that the release tag matches the package.json version before proceeding with the deployment, ensuring versions are always bumped before releases.
Docker-compose Deployment Setup
For docker-compose deployments, create a restart script on the server (outside the container):
Make the script executable and set the environment variable:
chmod +x /home/user/poke-docker.sh export RESTART_SCRIPT=/home/user/poke-docker.shThis ensures the restart endpoint pulls new Docker images before restarting containers.
Testing
All changes follow TDD principles with comprehensive test coverage:
RESTART_SCRIPTis configuredBenefits
Setup Instructions
After merging:
RESTART_TOKENenvironment variable to server's.envfilescripts/poke-docker.sh.example)chmod +x /path/to/poke-docker.shRESTART_SCRIPT=/path/to/poke-docker.shin your environmentreleaseenvironment with required reviewers (Settings > Environments)Notes
permissions: contents: readfollowing security best practicesOriginal prompt
Context
Currently, restarting the server after a deployment requires logging into the server manually. We'd like to streamline this process by using a GitHub Actions workflow that can safely trigger the server’s restart (via our existing “down/up poke” script) when a new release is published.
Proposal
Create a GitHub Actions release workflow that:
Security and Configuration
releaseenvironment).Health Check and Monitoring
To verify successful deployment:
/healthendpoint that returns the current application version./healthafter triggering a restart.Example check:
If the check fails within a set timeout (for example, one minute), send an alert.
Benefits
Open Questions
——
Below in the refined set of tasks:
GitHub Actions Release Workflow - Implementation l
Objective
Automate server restarts after GitHub releases are published, eliminating the need to manually SSH into the server.
Agreed Configuration
Health Endpoint
{ "version": "1.2.3", "status": "ok" }GET /healthRestart Endpoint
POST /restartAuthorization: Bearer <RESTART_TOKEN>Downtime Handling
Notifications
Polling Configuration
Version Matching
v1.2.3→ expect health check to return"1.2.3"Implementation Order
PR #1: Health Endpoint
Files to create/modify:
src/routes/health.ts- New health check endpointRequirements:
GET /healthroute{ "version": "x.y.z", "status": "ok" }package.jsonv1/index.tsif needed, or root level)PR #2: Restart Endpoint
Files to create/modify:
src/middleware/auth.ts- Token authentication middlewaresrc/routes/restart.ts- Restart endpoint.env.example- Document RESTART_TOKENRequirements:
Authorization: Bearer <token>headerRESTART_TOKENPOST /restartroute protected by auth middleware.env.examplewithRESTART_TOKEN=your-secret-token-herePR #3: GitHub Actions Release Workflow
Files to create/modify:
.github/workflows/release.yml- New release workflowREADME.md- Document deployment setup and required secretsRequirements:
Workflow Configuration
on: release: types: [published]releaseenvironment with protection rules (manual approval)Workflow Steps
1...
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.