fix: version commit dibaca live per-request + CI polling anti-stale 20x15s
This commit is contained in:
@@ -149,13 +149,28 @@ jobs:
|
|||||||
(cd /home/code/flowsight && git fetch origin main && git reset --hard origin/main || true) && \
|
(cd /home/code/flowsight && git fetch origin main && git reset --hard origin/main || true) && \
|
||||||
sudo mkdir -p /var/lib/flowsight/data && sudo chown -R code:code /var/lib/flowsight && \
|
sudo mkdir -p /var/lib/flowsight/data && sudo chown -R code:code /var/lib/flowsight && \
|
||||||
(sudo cp /home/code/flowsight/deploy/flowsight.service /etc/systemd/system/flowsight.service && sudo systemctl daemon-reload || true) && \
|
(sudo cp /home/code/flowsight/deploy/flowsight.service /etc/systemd/system/flowsight.service && sudo systemctl daemon-reload || true) && \
|
||||||
|
echo -n "$GITHUB_SHA" | sudo tee /var/lib/flowsight/version.txt >/dev/null && \
|
||||||
|
sudo chown code:code /var/lib/flowsight/version.txt && \
|
||||||
sudo systemctl enable --now flowsight && \
|
sudo systemctl enable --now flowsight && \
|
||||||
sudo systemctl restart flowsight && \
|
sudo systemctl restart flowsight && \
|
||||||
sleep 3 && \
|
sleep 3 && \
|
||||||
sudo systemctl status flowsight --no-pager --no-legend | head -5"
|
sudo systemctl status flowsight --no-pager --no-legend | head -5"
|
||||||
|
|
||||||
- name: Verify service anti-stale
|
- name: Verify service anti-stale
|
||||||
|
env:
|
||||||
|
PUSHED_SHA: ${{ github.sha }}
|
||||||
run: |
|
run: |
|
||||||
ssh "$VPS_USER@$VPS_HOST" \
|
ssh "$VPS_USER@$VPS_HOST" \
|
||||||
"curl -s -o /dev/null -w 'local:%{http_code}\n' http://localhost:4022/api/health && \
|
"curl -s -o /dev/null -w 'local:%{http_code}\n' http://localhost:4022/api/health && \
|
||||||
curl -sk -o /dev/null -w 'public:%{http_code}\n' https://sectors-hackaton.asepharyana.my.id/api/health"
|
curl -sk -o /dev/null -w 'public:%{http_code}\n' https://sectors-hackaton.asepharyana.my.id/api/health"
|
||||||
|
for i in $(seq 1 20); do
|
||||||
|
LIVE=$(curl -sk https://sectors-hackaton.asepharyana.my.id/api/version 2>/dev/null | python3 -c "import json,sys; print(json.load(sys.stdin).get('commit',''))" 2>/dev/null || true)
|
||||||
|
echo "attempt $i/20: live=${LIVE:0:7} want=${PUSHED_SHA:0:7}"
|
||||||
|
if [ -n "$LIVE" ] && [ "$LIVE" = "$PUSHED_SHA" ]; then
|
||||||
|
echo "Anti-stale OK: live commit matches pushed SHA"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
sleep 15
|
||||||
|
done
|
||||||
|
echo "STALE: live commit differs from pushed SHA after 5 min"
|
||||||
|
exit 1
|
||||||
|
|||||||
@@ -35,8 +35,7 @@ type Server struct {
|
|||||||
LLM *llm.Client
|
LLM *llm.Client
|
||||||
Validate *validator.Validate
|
Validate *validator.Validate
|
||||||
Hub *Hub
|
Hub *Hub
|
||||||
// Commit + StartedAt power /api/version (CI anti-stale proof).
|
// StartedAt powers /api/version (CI anti-stale proof: process age).
|
||||||
Commit string
|
|
||||||
StartedAt time.Time
|
StartedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +47,6 @@ func New(cfg config.Config, db *store.DB, cache *store.Cache, s *sectors.Client)
|
|||||||
Cfg: cfg, DB: db, Sectors: s, Sched: sched, LLM: llmc,
|
Cfg: cfg, DB: db, Sectors: s, Sched: sched, LLM: llmc,
|
||||||
Validate: validator.New(),
|
Validate: validator.New(),
|
||||||
Hub: NewHub(),
|
Hub: NewHub(),
|
||||||
Commit: readCommit(),
|
|
||||||
StartedAt: time.Now(),
|
StartedAt: time.Now(),
|
||||||
}
|
}
|
||||||
srv.Engine = &routines.Engine{DB: db, Notifier: sched.Notifier, UserKey: cfg.DemoUserKey,
|
srv.Engine = &routines.Engine{DB: db, Notifier: sched.Notifier, UserKey: cfg.DemoUserKey,
|
||||||
|
|||||||
@@ -9,28 +9,29 @@ import (
|
|||||||
|
|
||||||
// Version serves GET /api/version: deployed commit + process start time so CI
|
// Version serves GET /api/version: deployed commit + process start time so CI
|
||||||
// can prove the live process is the freshly deployed one (anti-stale).
|
// can prove the live process is the freshly deployed one (anti-stale).
|
||||||
// Commit is resolved once at startup (see readCommit); an old process keeps
|
// Commit is read LIVE per request (not cached): CI writes version.txt before
|
||||||
// reporting its old commit even after CI writes a new version.txt.
|
// restarting, and a stale process is caught because its started_at predates
|
||||||
|
// the deploy. Both fields together = full proof.
|
||||||
func (s *Server) Version(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) Version(w http.ResponseWriter, r *http.Request) {
|
||||||
writeJSON(w, http.StatusOK, map[string]any{
|
writeJSON(w, http.StatusOK, map[string]any{
|
||||||
"commit": s.Commit,
|
"commit": readCommitLive(),
|
||||||
"started_at": s.StartedAt.UTC().Format(time.RFC3339),
|
"started_at": s.StartedAt.UTC().Format(time.RFC3339),
|
||||||
"google_configured": s.Cfg.HasGoogle(),
|
"google_configured": s.Cfg.HasGoogle(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// readCommit resolves the deployed commit once at startup: CI writes
|
// readCommitLive resolves the deployed commit per request: version.txt
|
||||||
// $GITHUB_SHA to version.txt (WorkingDirectory) before restarting.
|
// (written by CI before every restart) wins, then startup env.
|
||||||
func readCommit() string {
|
func readCommitLive() string {
|
||||||
if v := strings.TrimSpace(os.Getenv("FLOWSIGHT_COMMIT")); v != "" {
|
for _, p := range []string{"/var/lib/flowsight/version.txt", "version.txt"} {
|
||||||
return v
|
|
||||||
}
|
|
||||||
for _, p := range []string{"version.txt", "/var/lib/flowsight/version.txt"} {
|
|
||||||
if b, err := os.ReadFile(p); err == nil {
|
if b, err := os.ReadFile(p); err == nil {
|
||||||
if v := strings.TrimSpace(string(b)); v != "" {
|
if v := strings.TrimSpace(string(b)); v != "" {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if v := strings.TrimSpace(os.Getenv("FLOWSIGHT_COMMIT")); v != "" {
|
||||||
|
return v
|
||||||
|
}
|
||||||
return "unknown"
|
return "unknown"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user