Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ dependencies = [
"requests>=2.34.2",
"rq>=2.12.0",
"psycopg[binary]>=3.3.6",
"tzdata>=2026.4",
]

[build-system]
Expand Down
2 changes: 2 additions & 0 deletions src/makeitso/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from makeitso.config import configs
from makeitso.extensions import bootstrap, csrf, db, job_queue, migrate, oauth
from makeitso.local_time import local_time


def create_app(config_name: str | None = None) -> Flask:
Expand All @@ -23,6 +24,7 @@ def create_app(config_name: str | None = None) -> Flask:
migrate.init_app(app, db)
job_queue.init_app(app)
oauth.init_app(app)
app.add_template_filter(local_time)

from makeitso import models # noqa: F401 (registers the models with SQLAlchemy)
from makeitso.auth import bp as auth_bp
Expand Down
11 changes: 11 additions & 0 deletions src/makeitso/local_time.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from datetime import UTC, datetime
from zoneinfo import ZoneInfo

LOCAL_TZ = ZoneInfo("America/Vancouver")


def local_time(dt: datetime, fmt: str = "%b %d, %Y %H:%M Vancouver time") -> str:
# Naive datetimes are UTC
if dt.tzinfo is None:
dt = dt.replace(tzinfo=UTC)
return dt.astimezone(LOCAL_TZ).strftime(fmt)
3 changes: 2 additions & 1 deletion src/makeitso/monitor/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
)

from makeitso.extensions import job_queue
from makeitso.local_time import local_time

# Most jobs to show per queue and per registry, so old failed jobs don't pile up on the page
MAX_JOBS = 50
Expand Down Expand Up @@ -73,7 +74,7 @@ def get_queue_data(queue: Queue):
JobData(
id=job.id,
status=job.get_status().value,
started_at=(job.started_at.strftime("%b %d, %Y %H:%M") if job.started_at else None),
started_at=(local_time(job.started_at) if job.started_at else None),
execution_time=_execution_time(job),
)
for job in jobs
Expand Down
7 changes: 4 additions & 3 deletions src/makeitso/stacks/forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from flask_wtf import FlaskForm
from github import GithubException
from wtforms import BooleanField, Field, StringField, TextAreaField
from wtforms import BooleanField, Field, StringField, SubmitField, TextAreaField
from wtforms.validators import DataRequired, Regexp, ValidationError

from makeitso.extensions import db
Expand Down Expand Up @@ -81,13 +81,14 @@ def _strip(value: str | None) -> str | None:


class LockForm(FlaskForm):
locked = BooleanField("Lock this stack")
lock = SubmitField("Lock")
unlock = SubmitField("Unlock")
lock_reason = TextAreaField(
"Reason", description="Shown on the stack page. Needed when locking.", filters=[_strip]
)

def validate_lock_reason(self, field: Field) -> None:
if self.locked.data and not field.data:
if self.lock.data and not field.data:
raise ValidationError("Give a reason for locking the stack")


Expand Down
2 changes: 1 addition & 1 deletion src/makeitso/stacks/views/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def post(self, stack_id: int):
form = _lock_form(stack)
if not form.validate_on_submit():
return _render(stack, form, _env_var_form())
stack.locked = form.locked.data
stack.locked = form.lock.data
stack.lock_reason = form.lock_reason.data if stack.locked else None
db.session.commit()
flash("Stack locked" if stack.locked else "Stack unlocked", "success")
Expand Down
2 changes: 1 addition & 1 deletion src/makeitso/templates/deploys/detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ <h1 class="h4 mb-0">
<p class="mb-2">{{ deploy.commit.commit_message }}</p>
{% set details = [
("person", "Author", deploy.commit.author_name),
("clock", "Started", deploy.started_at.strftime("%b %d, %Y %H:%M")),
("clock", "Started", deploy.started_at|local_time),
("person-check", "Deployed by", deployed_by(deploy)),
] %}
<ul class="list-inline small text-muted mb-4">
Expand Down
2 changes: 1 addition & 1 deletion src/makeitso/templates/deploys/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
{{ bypass_badge(deploy) }}
</td>
<td class="text-nowrap">{{ deployed_by(deploy) }}</td>
<td class="text-nowrap">{{ deploy.started_at.strftime("%b %d, %Y %H:%M") }}</td>
<td class="text-nowrap">{{ deploy.started_at|local_time }}</td>
<td class="text-nowrap">{{ deploy.elapsed }}</td>
<td><a class="text-nowrap text-decoration-none" href="{{ url_for('stacks.deploys.detail', stack_id=stack.id, deploy_id=deploy.id) }}">{{ render_icon("terminal") }} View log</a></td>
</tr>
Expand Down
4 changes: 2 additions & 2 deletions src/makeitso/templates/main/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ <h1 class="h3 mb-0">Stacks</h1>
<a href="{{ stack_url }}" class="fw-semibold">{{ stack.organization }}/{{ stack.repository }}</a>
<span class="badge rounded-pill text-bg-warning ms-1">{{ stack.environment }}</span>
{% if stack.locked %}
<span class="badge text-bg-secondary ms-1" title="{{ stack.lock_reason }}">Locked</span>
<span class="ms-1" title="Locked: {{ stack.lock_reason }}">{{ render_icon("lock-fill", color="secondary") }}</span>
{% endif %}
</td>
<td><code>{{ stack.branch }}</code></td>
Expand All @@ -56,7 +56,7 @@ <h1 class="h3 mb-0">Stacks</h1>
{% elif state.latest %}
{{ status_badge(state.latest.status) }}
<span class="small text-muted">
{{ state.latest.started_at.strftime("%b %d, %H:%M") }} by {{ deployed_by(state.latest) }}
{{ state.latest.started_at|local_time("%b %d, %H:%M Vancouver time") }} by {{ deployed_by(state.latest) }}
</span>
{% else %}
<span class="text-muted">no deploys yet</span>
Expand Down
2 changes: 1 addition & 1 deletion src/makeitso/templates/stacks/_commit_row.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
target="_blank" rel="noopener" class="text-muted">#{{ commit.pull_request_number }}</a>
{% endif %}
<div class="small text-muted">
<code>{{ commit.short_sha }}</code> · {{ commit.committed_at.strftime("%b %d, %Y %H:%M") }}
<code>{{ commit.short_sha }}</code> · {{ commit.committed_at|local_time }}
</div>
</div>
{% if show_deploy %}
Expand Down
4 changes: 2 additions & 2 deletions src/makeitso/templates/stacks/_commits.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<p class="small text-muted mb-2">Syncing with GitHub…</p>
{% else %}
<p class="small text-muted mb-2">
{% if stack.synced_at %}Last synced {{ stack.synced_at.strftime("%b %d, %Y %H:%M") }}{% else %}Never synced{% endif %}
{% if stack.synced_at %}Last synced {{ stack.synced_at|local_time }}{% else %}Never synced{% endif %}
</p>
{% endif %}

Expand Down Expand Up @@ -85,7 +85,7 @@ <h2 class="h5">Previous deploys</h2>
{{ bypass_badge(deploy) }}
<span class="small text-muted d-inline-flex align-items-center gap-3 text-nowrap">
<span title="Deployed by">{{ render_icon("person-check") }} {{ deployed_by(deploy) }}</span>
<span title="Started">{{ render_icon("clock") }} {{ deploy.started_at.strftime("%b %d, %Y %H:%M") }}</span>
<span title="Started">{{ render_icon("clock") }} {{ deploy.started_at|local_time }}</span>
<span title="Took">{{ render_icon("stopwatch") }} {{ deploy.elapsed }}</span>
</span>
<a class="text-nowrap text-decoration-none" href="{{ url_for('stacks.deploys.detail', stack_id=stack.id, deploy_id=deploy.id) }}">{{ render_icon("terminal") }} View log</a>
Expand Down
10 changes: 7 additions & 3 deletions src/makeitso/templates/stacks/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ <h1 class="h4 pb-2">Lock deploys</h1>
</p>
<form method="post" action="{{ url_for('stacks.lock', stack_id=stack.id) }}" class="mb-5" style="max-width: 40rem" novalidate>
{{ lock_form.hidden_tag() }}
{{ render_field(lock_form.locked) }}
{{ render_field(lock_form.lock_reason, rows=2, placeholder="e.g. Release freeze until Monday") }}
<button type="submit" class="btn btn-primary">Save</button>
{% if stack.locked %}
<p>Locked: {{ stack.lock_reason }}</p>
<button type="submit" name="lock-unlock" value="y" class="btn btn-outline-secondary d-inline-flex align-items-center gap-2">{{ render_icon("unlock-fill") }} Unlock</button>
{% else %}
{{ render_field(lock_form.lock_reason, rows=2, placeholder="e.g. Release freeze until Monday") }}
<button type="submit" name="lock-lock" value="y" class="btn btn-warning d-inline-flex align-items-center gap-2">{{ render_icon("lock-fill") }} Lock</button>
{% endif %}
</form>

<h1 class="h4 pb-2">Environment variables</h1>
Expand Down
2 changes: 2 additions & 0 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading