Compare commits

...

2 Commits

Author SHA1 Message Date
Sergey Antropoff fd0bf89e9e Исправлен VERSION до 0.1.3; убран авто-bump из make push.
devops-tools/wrapped/wrapped-build/pipeline/head This commit looks good
Упрощён экран «Токен выдан»: чеклист/trust убраны, Share и Download QR — иконки под QR.
2026-07-29 14:15:07 +03:00
Sergey Antropoff a4b750afef Убраны short-sha теги образа: в Hub/Harbor публикуются только SemVer и latest.
devops-tools/wrapped/wrapped-build/pipeline/head This commit looks good
devops-tools/wrapped/wrapped-deploy/pipeline/head This commit looks good
2026-07-29 13:41:17 +03:00
10 changed files with 92 additions and 88 deletions
Vendored
+10 -17
View File
@@ -5,7 +5,7 @@
// 2) при успехе — trigger Deploy с wait:false и agent none → Builder-под умирает
// 3) Deploy стартует отдельно уже без Builder
//
// Версия образа = VERSION из коммита. Bump: make bump-patch / make push.
// Версия образа = VERSION из коммита (без auto-bump). Ручной bump: make bump-patch.
//
// Credentials (Global):
// harbor-devops-tools-push-pull-access — Harbor devops-tools (robot)
@@ -30,7 +30,6 @@ pipeline {
HARBOR_REGISTRY = 'hub.antropoff.ru'
HARBOR_IMAGE = 'hub.antropoff.ru/devops-tools/wrapped'
DOCKERHUB_IMAGE = 'inecs/wrapped'
// RELEASE_TAG — после checkout (с agent none GIT_COMMIT ещё нет → валидация env падает)
BUILDX_BUILDER = "jenkins-wrapped-${env.BUILD_NUMBER}"
DEPLOY_JOB = 'devops-tools/wrapped/wrapped-deploy/main'
TZ = 'Europe/Moscow'
@@ -60,12 +59,7 @@ pipeline {
if (!env.IMAGE_VERSION) {
error('VERSION file is empty')
}
if (!env.GIT_COMMIT) {
error('GIT_COMMIT is empty after checkout')
}
env.RELEASE_TAG = env.GIT_COMMIT.take(7)
echo "IMAGE_VERSION from VERSION → ${env.IMAGE_VERSION}"
echo "RELEASE_TAG → ${env.RELEASE_TAG}"
}
}
}
@@ -89,7 +83,7 @@ pipeline {
set -eux
test -n "${IMAGE_VERSION}"
echo "Building tags: ${IMAGE_VERSION}, ${RELEASE_TAG}, latest"
echo "Building tags: ${IMAGE_VERSION}, latest (no short-sha)"
echo "$HARBOR_PASS" | docker login "$HARBOR_REGISTRY" -u "$HARBOR_USER" --password-stdin
echo "$DOCKERHUB_PASS" | docker login -u "$DOCKERHUB_USER" --password-stdin
@@ -98,27 +92,26 @@ pipeline {
docker buildx create --name "$BUILDX_BUILDER" --driver docker-container --use
docker buildx inspect --bootstrap >/dev/null
# Arch-слои только в Harbor (промежуточные теги), не в Docker Hub
docker buildx build \
--platform linux/amd64 \
--provenance=false --sbom=false --push \
-t "${HARBOR_IMAGE}:${RELEASE_TAG}-amd64" \
-t "${DOCKERHUB_IMAGE}:${RELEASE_TAG}-amd64" \
-t "${HARBOR_IMAGE}:${IMAGE_VERSION}-amd64" \
-f Dockerfile .
docker buildx build \
--platform linux/arm64 \
--provenance=false --sbom=false --push \
-t "${HARBOR_IMAGE}:${RELEASE_TAG}-arm64" \
-t "${DOCKERHUB_IMAGE}:${RELEASE_TAG}-arm64" \
-t "${HARBOR_IMAGE}:${IMAGE_VERSION}-arm64" \
-f Dockerfile .
# Публичные теги: только SemVer + latest
for IMAGE in "$HARBOR_IMAGE" "$DOCKERHUB_IMAGE"; do
docker buildx imagetools create \
-t "${IMAGE}:${RELEASE_TAG}" \
-t "${IMAGE}:${IMAGE_VERSION}" \
-t "${IMAGE}:latest" \
"${IMAGE}:${RELEASE_TAG}-amd64" \
"${IMAGE}:${RELEASE_TAG}-arm64"
"${HARBOR_IMAGE}:${IMAGE_VERSION}-amd64" \
"${HARBOR_IMAGE}:${IMAGE_VERSION}-arm64"
done
echo "--- Harbor ---"
@@ -146,7 +139,7 @@ pipeline {
}
}
success {
echo "✓ Build OK: ${DOCKERHUB_IMAGE}:{${RELEASE_TAG},${IMAGE_VERSION},latest}"
echo "✓ Build OK: ${DOCKERHUB_IMAGE}:{${IMAGE_VERSION},latest}"
}
failure {
echo "✗ Build/push не удались — Deploy не запускается"
@@ -185,7 +178,7 @@ pipeline {
post {
success {
echo "✓ Version: ${IMAGE_VERSION}"
echo "✓ Image: ${DOCKERHUB_IMAGE}:{${RELEASE_TAG},${IMAGE_VERSION},latest}"
echo "✓ Image: ${DOCKERHUB_IMAGE}:{${IMAGE_VERSION},latest}"
echo "✓ Deploy: ${DEPLOY_JOB} triggered (async)"
}
failure {
+3 -3
View File
@@ -32,7 +32,7 @@ help:
@echo " make bump-minor VERSION +0.1.0"
@echo " make release Multi-arch build & push $(FULL_IMAGE)"
@echo " platforms: $(RELEASE_PLATFORMS)"
@echo " make push bump-patch + git add/commit (prompt) + push"
@echo " make push git add/commit (prompt) + push (без auto-bump)"
@echo " make helm-lint Lint Helm chart"
@echo " make helm-package Package Helm chart"
@echo " make clean Remove containers, volumes, local image"
@@ -136,7 +136,7 @@ clean:
-docker buildx rm $(BUILDX_BUILDER) 2>/dev/null || true
rm -rf dist
# Same flow as proxmox_api_simulator / infra: bump SemVer, stage, multiline commit, push.
# Ручной SemVer (не вызывается из make push).
bump-patch:
@PYTHONPATH=. python3 scripts/bump_version.py patch
@echo "VERSION → $$(cat VERSION)"
@@ -153,7 +153,7 @@ version-commit:
git commit -m "Bump version to $$(cat VERSION)."; \
fi
push: bump-patch
push:
@set -e; \
git add .; \
echo "=== staged ==="; \
+4 -4
View File
@@ -340,7 +340,7 @@ services:
### UX (v0.1.3+)
- После создания: **QR** на share-link, **скачать QR (PNG)**, **Web Share** (если есть `navigator.share`), чеклист и trust-строка про `#key`; отдельные кнопки Copy для ссылки / токена / пароля; пароль не советуется слать в той же переписке.
- После создания: **QR** на share-link, иконки **скачать QR (PNG)** и **Web Share** (если есть `navigator.share`) под QR; отдельные кнопки Copy для ссылки / токена / пароля; пароль не советуется слать в той же переписке.
- Create: счётчик размера `≈ used / max` и предупреждение near-limit (сверх лимита — `create.tooLarge`).
- Unwrap: Enter в поле пароля отправляет форму; после `password_required` / `bad_password` — focus+select; при ≥2 элементах — **скачать всё** (zip через JSZip); trust-строка на результате; спокойный экран «ссылка недоступна» для already used / expired (anti-enumeration); отдельные состояния для `password_locked`, rate limit, CAPTCHA, ошибки расшифровки.
- Картинки после unwrap: inline-превью и **lightbox** (тап/клик).
@@ -443,7 +443,7 @@ docker buildx build \
| Harbor | `hub.antropoff.ru/devops-tools/wrapped` |
| Docker Hub | `inecs/wrapped` |
Теги на каждый реестр: `:<semver>` (ровно из `VERSION` в коммите), `:<short-sha>`, `:latest`.
Публичные теги на каждый реестр: `:<semver>` (из `VERSION` в коммите) и `:latest`. Short-sha больше не пушится. Промежуточные `:<semver>-amd64` / `-arm64` остаются только в Harbor для сборки multi-arch manifest.
### Версионирование
@@ -452,8 +452,8 @@ docker buildx build \
| Где | Поведение |
|-----|-----------|
| UI (модалка «?») | бейдж `vX.Y.Z` |
| `make bump-patch` / `bump-minor` | ручной bump |
| `make push` | автоматически `bump-patch`, затем commit/push |
| `make bump-patch` / `bump-minor` | ручной bump (по желанию) |
| `make push` | commit/push **без** auto-bump |
| Jenkins (`Jenkinsfile`) | читает `VERSION` из коммита **без** доп. bump → те же теги в образе и на кластере |
Что в `VERSION` запушили — то и уйдёт в Harbor/Hub/деплой (и в футер модалки внутри образа).
+1 -1
View File
@@ -1 +1 @@
0.1.4
0.1.3
+56 -40
View File
@@ -322,46 +322,6 @@ html[data-theme="dark"] .icon-btn:hover {
font-size: 0.84rem;
line-height: 1.4;
}
.success-checklist {
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: 0.35rem;
}
.success-checklist li {
position: relative;
padding-left: 1.35rem;
color: var(--muted);
font-size: 0.88rem;
line-height: 1.4;
}
.success-checklist li::before {
content: "";
position: absolute;
left: 0;
top: 0.35rem;
width: 0.55rem;
height: 0.55rem;
border-radius: 2px;
border: 1.5px solid var(--accent-2);
opacity: 0.85;
}
.success-trust {
margin: 0;
font-size: 0.84rem;
line-height: 1.45;
}
.success-actions {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-top: 0.35rem;
}
.success-actions .btn {
flex: 1 1 auto;
min-width: 8rem;
}
.size-meter {
margin: 0;
font-variant-numeric: tabular-nums;
@@ -381,6 +341,7 @@ html[data-theme="dark"] .icon-btn:hover {
border-radius: 16px;
background: var(--panel);
min-width: 0;
overflow: visible;
}
.share-qr {
width: 180px;
@@ -405,6 +366,61 @@ html[data-theme="dark"] .icon-btn:hover {
max-width: 11rem;
line-height: 1.35;
}
.success-qr-actions {
display: flex;
align-items: center;
justify-content: center;
gap: 0.4rem;
margin-top: 0.15rem;
}
.qr-action-btn {
position: relative;
width: 2.35rem;
height: 2.35rem;
border: 1px solid var(--line);
border-radius: 10px;
background: transparent;
color: var(--muted);
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0;
transition: color 0.15s, background 0.15s, border-color 0.15s;
}
.qr-action-btn:hover,
.qr-action-btn:focus-visible {
color: var(--accent-2);
background: rgba(75, 134, 240, 0.1);
border-color: rgba(75, 134, 240, 0.35);
outline: none;
}
.qr-action-btn:active {
transform: scale(0.96);
}
.qr-action-btn .ui-tooltip {
left: 50%;
right: auto;
bottom: calc(100% + 0.5rem);
transform: translateX(-50%) translateY(4px);
white-space: nowrap;
}
.qr-action-btn .ui-tooltip::after {
left: 50%;
right: auto;
transform: translateX(-50%);
}
.qr-action-btn:hover .ui-tooltip,
.qr-action-btn:focus-visible .ui-tooltip {
opacity: 1;
visibility: visible;
transform: translateX(-50%);
}
.success-panel > .expires-meta {
width: 100%;
justify-self: stretch;
margin-top: 0.15rem;
}
@media (max-width: 860px) {
.success-layout {
grid-template-columns: 1fr;
-3
View File
@@ -31,7 +31,6 @@
expiresMeta: document.getElementById("expires-meta"),
captchaSlot: document.getElementById("captcha-slot"),
sizeMeter: document.getElementById("size-meter"),
checkPasswordItem: document.getElementById("check-password-item"),
shareNative: document.getElementById("share-native"),
downloadQr: document.getElementById("download-qr"),
};
@@ -334,11 +333,9 @@
if (password) {
els.sharePassword.value = password;
els.passwordBlock.classList.remove("hidden");
els.checkPasswordItem?.classList.remove("hidden");
} else {
els.sharePassword.value = "";
els.passwordBlock.classList.add("hidden");
els.checkPasswordItem?.classList.add("hidden");
}
renderShareQr(link);
syncShareControls();
+14 -16
View File
@@ -66,15 +66,6 @@
</span>
</div>
<ul class="success-checklist" id="success-checklist">
<li data-i18n="create.checkLink">Copy the share link</li>
<li id="check-password-item" class="hidden" data-i18n="create.checkPassword">Send the password in a separate message</li>
<li data-i18n="create.checkExpires">Note the expiry time</li>
</ul>
<p class="hint success-trust" data-i18n="create.trustKey">
The encryption key lives only in the link #fragment — the server never sees it.
</p>
<div class="success-layout">
<div class="success-main">
<div id="success-password-block" class="success-password-block hidden">
@@ -103,21 +94,28 @@
<input id="share-token" class="mono" readonly />
<button type="button" class="btn" id="copy-token" data-i18n="common.copy">Copy</button>
</div>
<div class="success-actions">
<button type="button" class="btn hidden" id="share-native" data-i18n="create.share">Share</button>
<button type="button" class="btn" id="download-qr" data-i18n="create.downloadQr">Download QR</button>
</div>
<p class="expires-meta" id="expires-meta"></p>
</div>
<div class="success-qr" aria-label="QR code">
<div id="share-qr" class="share-qr"></div>
<p class="hint success-qr-hint" data-i18n="create.qrHint">Scan to open the share link</p>
<div class="success-qr-actions">
<button type="button" class="qr-action-btn hidden" id="share-native" aria-describedby="share-native-tip">
<i class="fa-solid fa-share-nodes" aria-hidden="true"></i>
<span class="sr-only" data-i18n="create.share">Share</span>
<span class="ui-tooltip" id="share-native-tip" role="tooltip" data-i18n="create.share">Share</span>
</button>
<button type="button" class="qr-action-btn" id="download-qr" aria-describedby="download-qr-tip">
<i class="fa-solid fa-download" aria-hidden="true"></i>
<span class="sr-only" data-i18n="create.downloadQr">Download QR</span>
<span class="ui-tooltip" id="download-qr-tip" role="tooltip" data-i18n="create.downloadQr">Download QR</span>
</button>
</div>
</div>
</div>
<p class="expires-meta" id="expires-meta"></p>
<button type="button" class="btn ghost" id="create-another" data-i18n="create.another">Create another</button>
</div>
</section>
+2 -2
View File
@@ -2,5 +2,5 @@ apiVersion: v2
name: wrapped
description: Zero-knowledge one-time encrypted drop (Wrapped)
type: application
version: 0.1.4
appVersion: "0.1.4"
version: 0.1.3
appVersion: "0.1.3"
+1 -1
View File
@@ -2,7 +2,7 @@ replicaCount: 1
image:
repository: inecs/wrapped
tag: "0.1.4"
tag: "0.1.3"
pullPolicy: IfNotPresent
service:
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "wrapped"
version = "0.1.4"
version = "0.1.3"
description = "Zero-knowledge one-time encrypted drop service"
readme = "README.md"
requires-python = ">=3.12"