Tag built images with the commit's short hash (closes #239)
Check / check (pull_request) Successful in 5m31s

Builds are tagged upaas-<app>:<short hash>, git's short form of
the commit checked out, instead of the deployment number. The clone
prints the short hash and fails without one.

A redeploy of a commit gives the tag to the new image. The cleanup
after a deploy now also finds the app's untagged images among those
its deployments recorded, and removes them by ID once the app neither
runs them nor would roll back to them. It keeps every image any app
uses, since apps that build the same commit can share one.

commit_sha is now saved on update so manual deploys keep the commit
read from the clone.

Model: opus-5-5
This commit was merged in pull request #250.
This commit is contained in:
2026-10-01 22:33:20 +02:00
parent 047945cabf
commit 9488e2faef
10 changed files with 701 additions and 123 deletions
+42 -2
View File
@@ -203,11 +203,12 @@ func (d *Deployment) insert(ctx context.Context) error {
func (d *Deployment) update(ctx context.Context) error {
query := `
UPDATE deployments SET
image_id = ?, container_id = ?, status = ?, logs = ?, finished_at = ?
commit_sha = ?, image_id = ?, container_id = ?, status = ?, logs = ?,
finished_at = ?
WHERE id = ?`
_, err := d.db.Exec(ctx, query,
d.ImageID, d.ContainerID, d.Status, d.Logs, d.FinishedAt, d.ID,
d.CommitSHA, d.ImageID, d.ContainerID, d.Status, d.Logs, d.FinishedAt, d.ID,
)
return err
@@ -295,6 +296,45 @@ func FindDeploymentsByAppID(
return deployments, nil
}
// FindDeploymentImageIDs returns the IDs of the images an app's
// deployments built or rolled back to.
func FindDeploymentImageIDs(
ctx context.Context,
deployDB *database.Database,
appID string,
) ([]string, error) {
rows, err := deployDB.Query(ctx, `
SELECT DISTINCT image_id FROM deployments
WHERE app_id = ? AND image_id IS NOT NULL`,
appID,
)
if err != nil {
return nil, fmt.Errorf("querying deployment image IDs: %w", err)
}
defer func() { _ = rows.Close() }()
var imageIDs []string
for rows.Next() {
var imageID string
scanErr := rows.Scan(&imageID)
if scanErr != nil {
return nil, fmt.Errorf("scanning deployment image ID: %w", scanErr)
}
imageIDs = append(imageIDs, imageID)
}
rowsErr := rows.Err()
if rowsErr != nil {
return nil, fmt.Errorf("iterating deployment image IDs: %w", rowsErr)
}
return imageIDs, nil
}
// LatestDeploymentForApp finds the most recent deployment for an app.
//
//nolint:nilnil // returning nil,nil is idiomatic for "not found" in Active Record