Add Gitea Actions CI, ArgoCD Application, and Gitea Packages wiring
- .gitea/workflows/ci.yml: build → seo:lint → e2e → image build/push → bump k8s image tag and commit back (paths-ignore + [skip ci] guard) - argocd/bcs-website-application.yaml: ArgoCD App (internal Gitea repoURL, k8s path) - k8s: image → Gitea Packages path; kustomization images newTag stanza - ADR-0007 (Gitea Actions + Packages), supersedes GHCR/GitHub bits of ADR-0001 - Reconcile gitops-deployment-strategy.md to Gitea Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
cd91c4b97c
commit
3dab3bc9fb
85
.gitea/workflows/ci.yml
Normal file
85
.gitea/workflows/ci.yml
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
# BlueCap Strategies CI — Gitea Actions (ADR-0007)
|
||||||
|
#
|
||||||
|
# Pipeline: install → build (typecheck) → seo:lint → e2e → build & push image to Gitea Packages
|
||||||
|
# → bump the image tag in k8s/ and commit back to main. ArgoCD then reconciles k3s.
|
||||||
|
#
|
||||||
|
# PREREQUISITES (homelab, verify before the first run — see docs/gitops-deployment-strategy.md):
|
||||||
|
# 1. Docker must be usable from the job container. The runner mounts /var/run/docker.sock; if
|
||||||
|
# jobs can't see it, enable socket passthrough in act_runner config or switch this to kaniko.
|
||||||
|
# 2. The RUNNER HOST's dockerd must treat 10.66.15.22:3000 as an insecure (HTTP) registry
|
||||||
|
# ("insecure-registries": ["10.66.15.22:3000"] in /etc/docker/daemon.json).
|
||||||
|
# 3. K3S must trust the same HTTP registry — add a registries.yaml entry (k3s_registry_mirrors)
|
||||||
|
# for 10.66.15.22:3000, then restart k3s, or the pods can't pull the image.
|
||||||
|
# 4. The Gitea container package should be PUBLIC (simplest). If PRIVATE, add an imagePullSecret
|
||||||
|
# (see k8s/deployment.yaml) and grant the run token package:write.
|
||||||
|
# 5. secrets.GITEA_TOKEN (auto-injected per run) needs write access to this repo (tag-bump commit)
|
||||||
|
# and the package registry.
|
||||||
|
|
||||||
|
name: CI
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
# Don't re-trigger on the CI tag-bump commit (touches k8s/) or docs-only changes.
|
||||||
|
paths-ignore:
|
||||||
|
- 'k8s/**'
|
||||||
|
- 'docs/**'
|
||||||
|
- 'planning/**'
|
||||||
|
- '**/*.md'
|
||||||
|
|
||||||
|
env:
|
||||||
|
IMAGE: 10.66.15.22:3000/bmr_bluecap/bcs-website
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Node 22
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build (typecheck + astro build)
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: SEO lint
|
||||||
|
run: npm run seo:lint
|
||||||
|
|
||||||
|
- name: End-to-end tests
|
||||||
|
run: |
|
||||||
|
npx playwright install --with-deps chromium
|
||||||
|
npm run test:e2e
|
||||||
|
|
||||||
|
- name: Compute image tag
|
||||||
|
id: tag
|
||||||
|
run: echo "sha=$(echo ${{ github.sha }} | cut -c1-12)" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Ensure docker + kustomize are available
|
||||||
|
run: |
|
||||||
|
command -v docker >/dev/null 2>&1 || { apt-get update && apt-get install -y docker.io; }
|
||||||
|
command -v kustomize >/dev/null 2>&1 || \
|
||||||
|
curl -sSL "https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv5.4.3/kustomize_v5.4.3_linux_amd64.tar.gz" \
|
||||||
|
| tar xz -C /usr/local/bin
|
||||||
|
|
||||||
|
- name: Build & push image to Gitea Packages
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.GITEA_TOKEN }}" | docker login 10.66.15.22:3000 -u "${{ github.actor }}" --password-stdin
|
||||||
|
docker build -t "$IMAGE:${{ steps.tag.outputs.sha }}" -t "$IMAGE:latest" .
|
||||||
|
docker push "$IMAGE:${{ steps.tag.outputs.sha }}"
|
||||||
|
docker push "$IMAGE:latest"
|
||||||
|
|
||||||
|
- name: Bump k8s image tag and commit back
|
||||||
|
run: |
|
||||||
|
git config user.name "gitea-actions[bot]"
|
||||||
|
git config user.email "gitea-actions@bmr_bluecap"
|
||||||
|
(cd k8s && kustomize edit set image "$IMAGE=$IMAGE:${{ steps.tag.outputs.sha }}")
|
||||||
|
git add k8s/kustomization.yaml
|
||||||
|
git diff --cached --quiet && { echo "no image change"; exit 0; }
|
||||||
|
git commit -m "ci: deploy ${{ steps.tag.outputs.sha }} [skip ci]"
|
||||||
|
git remote set-url origin "http://gitea-actions:${{ secrets.GITEA_TOKEN }}@10.66.15.22:3000/bmr_bluecap/bcs-website.git"
|
||||||
|
git push origin HEAD:main
|
||||||
24
argocd/bcs-website-application.yaml
Normal file
24
argocd/bcs-website-application.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# ArgoCD Application for the BlueCap Strategies site.
|
||||||
|
# Bootstrap: apply once (`kubectl apply -f argocd/bcs-website-application.yaml`) or add to the
|
||||||
|
# homelab-gitops app-of-apps. Kept OUT of k8s/ so ArgoCD does not try to manage this CR as part
|
||||||
|
# of the app itself. ArgoCD reaches Gitea over the internal HTTP URL (same as homelab-gitops).
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: bcs-website
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
repoURL: http://10.66.15.22:3000/bmr_bluecap/bcs-website.git
|
||||||
|
targetRevision: main
|
||||||
|
path: k8s
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: bluecap-strategies
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
@ -1,6 +1,8 @@
|
|||||||
# ADR-0001: GitOps deployment via ArgoCD (not Flux)
|
# ADR-0001: GitOps deployment via ArgoCD (not Flux)
|
||||||
|
|
||||||
**Status:** Accepted — 2026-07-15
|
**Status:** Accepted — 2026-07-15 · CI/registry specifics (GitHub Actions + GHCR) **superseded by
|
||||||
|
[ADR-0007](0007-gitea-actions-and-packages.md)** (Gitea Actions + Gitea Packages). The ArgoCD /
|
||||||
|
GitOps model here stands.
|
||||||
|
|
||||||
## Context
|
## Context
|
||||||
|
|
||||||
|
|||||||
33
docs/adr/0007-gitea-actions-and-packages.md
Normal file
33
docs/adr/0007-gitea-actions-and-packages.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# ADR-0007: CI on Gitea Actions, images in Gitea Packages
|
||||||
|
|
||||||
|
**Status:** Accepted — 2026-07-15 · **Supersedes** the GitHub Actions + GHCR specifics of
|
||||||
|
[ADR-0001](0001-gitops-with-argocd.md) (the ArgoCD/GitOps model itself stands).
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The repo lives on the homelab's self-hosted **Gitea** (`bmr_bluecap/bcs-website`), not GitHub, so
|
||||||
|
GitHub Actions and GHCR do not apply. Gitea runs an **`act_runner`** (GitHub-Actions-compatible)
|
||||||
|
and a built-in **container registry** (Gitea Packages, OCI `/v2/` confirmed live at
|
||||||
|
`10.66.15.22:3000`). The runner mounts `/var/run/docker.sock`; its label is `ubuntu-latest`
|
||||||
|
(jobs run in a `node:18-bullseye` container).
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
- **CI = Gitea Actions**, workflow at `.gitea/workflows/ci.yml`, `runs-on: ubuntu-latest`.
|
||||||
|
- **Registry = Gitea Packages** at `10.66.15.22:3000/bmr_bluecap/bcs-website`, immutable
|
||||||
|
`<git-sha>` tags. Auth via the run's automatic token.
|
||||||
|
- Pipeline: `npm ci` → build (typecheck) → `seo:lint` → Playwright e2e → build & push image →
|
||||||
|
bump the image tag in `k8s/kustomization.yaml` and commit back to `main` (`[skip ci]` +
|
||||||
|
`paths-ignore` to avoid a loop). **ArgoCD** then reconciles k3s (unchanged from ADR-0001).
|
||||||
|
- **Package visibility: public** (recommended) — the image contains only the compiled public
|
||||||
|
site, so a public package removes the need for a cluster imagePullSecret. Private + an
|
||||||
|
External-Secrets-managed pull secret is the documented alternative.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- No external CI/registry dependency; everything stays in the homelab.
|
||||||
|
- **New infra prerequisites** (see `docs/gitops-deployment-strategy.md`): k3s must trust the HTTP
|
||||||
|
registry (`registries.yaml` / `k3s_registry_mirrors` entry for `10.66.15.22:3000`); the runner
|
||||||
|
host's Docker daemon needs `10.66.15.22:3000` as an insecure registry; docker must be usable
|
||||||
|
from job containers (act_runner socket passthrough) or the build switches to kaniko.
|
||||||
|
- `GHCR`/`GitHub` references in ADR-0001 and older doc revisions are superseded by this ADR.
|
||||||
@ -14,3 +14,4 @@ Format: Status · Context · Decision · Consequences. Statuses: Proposed · Acc
|
|||||||
| [0004](0004-reuse-monylog-for-monitoring.md) | Reuse the monylog stack for ops monitoring (not Uptime Kuma) | Accepted |
|
| [0004](0004-reuse-monylog-for-monitoring.md) | Reuse the monylog stack for ops monitoring (not Uptime Kuma) | Accepted |
|
||||||
| [0005](0005-analytics-posthog-and-umami-trial.md) | Visitor analytics: PostHog + Umami side-by-side trial | Accepted |
|
| [0005](0005-analytics-posthog-and-umami-trial.md) | Visitor analytics: PostHog + Umami side-by-side trial | Accepted |
|
||||||
| [0006](0006-launch-insights-blog.md) | Launch a blog at /insights/ | Accepted |
|
| [0006](0006-launch-insights-blog.md) | Launch a blog at /insights/ | Accepted |
|
||||||
|
| [0007](0007-gitea-actions-and-packages.md) | CI on Gitea Actions, images in Gitea Packages | Accepted |
|
||||||
|
|||||||
@ -3,34 +3,49 @@
|
|||||||
## Goal
|
## Goal
|
||||||
|
|
||||||
Deploy the BlueCap Strategies Astro site to the existing k3s cluster using GitOps, without
|
Deploy the BlueCap Strategies Astro site to the existing k3s cluster using GitOps, without
|
||||||
giving GitHub Actions direct access to the homelab cluster.
|
giving Gitea Actions direct access to the homelab cluster.
|
||||||
|
|
||||||
The homelab already runs **ArgoCD** in k3s, so this strategy uses ArgoCD as the reconciler
|
The homelab already runs **ArgoCD** in k3s, so this strategy uses ArgoCD as the reconciler
|
||||||
rather than standing up a second GitOps controller (Flux). ArgoCD pulls from Git and GHCR; the
|
rather than standing up a second GitOps controller (Flux). ArgoCD pulls from Git and the image
|
||||||
cluster is never exposed to GitHub.
|
registry; the cluster is never exposed to the CI system.
|
||||||
|
|
||||||
Desired operating model:
|
Desired operating model:
|
||||||
|
|
||||||
1. Edit the site locally in this repository.
|
1. Edit the site locally in this repository.
|
||||||
2. Commit changes.
|
2. Commit changes.
|
||||||
3. Push to `main`.
|
3. Push to `main`.
|
||||||
4. GitHub Actions runs tests and builds a container image.
|
4. Gitea Actions runs tests and builds a container image.
|
||||||
5. GitHub Actions pushes the image to GHCR, tagged with the immutable `<git-sha>`.
|
5. Gitea Actions pushes the image to Gitea Packages, tagged with the immutable `<git-sha>`.
|
||||||
6. Git is updated with the new desired image tag (CI commits the tag into `k8s/`).
|
6. Git is updated with the new desired image tag (CI commits the tag into `k8s/`).
|
||||||
7. ArgoCD, running inside k3s, detects the Git change.
|
7. ArgoCD, running inside k3s, detects the Git change.
|
||||||
8. ArgoCD syncs the Kubernetes manifests (Kustomize).
|
8. ArgoCD syncs the Kubernetes manifests (Kustomize).
|
||||||
9. k3s pulls the new image and rolls the website deployment.
|
9. k3s pulls the new image and rolls the website deployment.
|
||||||
10. Traefik serves the updated site publicly.
|
10. Traefik serves the updated site publicly.
|
||||||
|
|
||||||
GitHub never receives kubeconfig or direct network access to the homelab cluster. The cluster
|
The CI runner never receives kubeconfig or direct network access to the homelab cluster. The cluster
|
||||||
pulls from Git and the image registry.
|
pulls from Git and the image registry.
|
||||||
|
|
||||||
## Prerequisites (not yet done)
|
> **Concrete implementation is Gitea, not GitHub/GHCR** — see [ADR-0007](adr/0007-gitea-actions-and-packages.md).
|
||||||
|
> CI = Gitea Actions (`.gitea/workflows/ci.yml`); registry = Gitea Packages
|
||||||
|
> (`10.66.15.22:3000/bmr_bluecap/bcs-website`); ArgoCD Application in `argocd/bcs-website-application.yaml`.
|
||||||
|
> Any lingering GitHub/GHCR wording below is the generic model; substitute Gitea/Gitea-Packages.
|
||||||
|
|
||||||
- **This repository is not yet a git repo.** GitOps requires a remote (GitHub) that both CI and
|
## Prerequisites
|
||||||
ArgoCD can read. `git init`, push to a GitHub repo, then wire ArgoCD to that repo.
|
|
||||||
- Decide the GHCR image path (replace the placeholder `ghcr.io/your-org/...` in
|
Done: repo pushed to Gitea (`bmr_bluecap/bcs-website`, private); `k8s/deployment.yaml` image set to
|
||||||
`k8s/deployment.yaml`).
|
the Gitea Packages path; ArgoCD Application manifest written.
|
||||||
|
|
||||||
|
**Still to do before the first deploy works (homelab infra):**
|
||||||
|
- **k3s must trust the HTTP registry.** Add a `registries.yaml` entry for `10.66.15.22:3000` as
|
||||||
|
insecure/HTTP (via the k3s role `k3s_registry_mirrors`), then restart k3s — otherwise pods can't
|
||||||
|
pull the image.
|
||||||
|
- **Runner host dockerd** needs `10.66.15.22:3000` in `insecure-registries` to push over HTTP.
|
||||||
|
- **Docker usable from job containers** (act_runner socket passthrough) — or switch the build to
|
||||||
|
kaniko.
|
||||||
|
- **Package visibility:** make the container package **public** (simplest; image is only the public
|
||||||
|
site), or keep it private and add an imagePullSecret (`k8s/deployment.yaml`), ideally via the
|
||||||
|
installed External Secrets operator.
|
||||||
|
- Apply the ArgoCD Application (once) or add it to the homelab-gitops app-of-apps.
|
||||||
|
|
||||||
## Cluster Findings
|
## Cluster Findings
|
||||||
|
|
||||||
@ -50,7 +65,7 @@ Edge / DNS / TLS (research 2026-06-05):
|
|||||||
## Repository & Image Strategy
|
## Repository & Image Strategy
|
||||||
|
|
||||||
- **Mono-repo:** Keep site source and k8s manifests in the same repository.
|
- **Mono-repo:** Keep site source and k8s manifests in the same repository.
|
||||||
- **GHCR:** Use GitHub Container Registry for images.
|
- **Gitea Packages:** Use Gitea's built-in container registry (`10.66.15.22:3000`) for images.
|
||||||
- **Immutable tags:** Deploy via `<git-sha>` tags, never `latest`. `latest` defeats ArgoCD's
|
- **Immutable tags:** Deploy via `<git-sha>` tags, never `latest`. `latest` defeats ArgoCD's
|
||||||
ability to detect and record what is actually running.
|
ability to detect and record what is actually running.
|
||||||
- **Manifests:** Plain Kustomize under `k8s/` (already present). ArgoCD consumes
|
- **Manifests:** Plain Kustomize under `k8s/` (already present). ArgoCD consumes
|
||||||
@ -76,7 +91,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: default
|
project: default
|
||||||
source:
|
source:
|
||||||
repoURL: https://github.com/<owner>/bcs-website.git
|
repoURL: http://10.66.15.22:3000/bmr_bluecap/bcs-website.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s
|
path: k8s
|
||||||
destination:
|
destination:
|
||||||
@ -99,7 +114,7 @@ spec:
|
|||||||
Two options — this strategy recommends **Option A** for simplicity and auditability:
|
Two options — this strategy recommends **Option A** for simplicity and auditability:
|
||||||
|
|
||||||
### Option A (recommended): CI commits the image tag
|
### Option A (recommended): CI commits the image tag
|
||||||
GitHub Actions, after pushing the image, patches the image tag in `k8s/` (via
|
Gitea Actions, after pushing the image, patches the image tag in `k8s/` (via
|
||||||
`kustomize edit set image` or a `newTag` field) and commits back to `main`. ArgoCD auto-syncs the
|
`kustomize edit set image` or a `newTag` field) and commits back to `main`. ArgoCD auto-syncs the
|
||||||
new tag. Every deploy is a Git commit traceable to a source SHA — clean rollback via `git revert`.
|
new tag. Every deploy is a Git commit traceable to a source SHA — clean rollback via `git revert`.
|
||||||
|
|
||||||
@ -107,26 +122,26 @@ Add to `k8s/kustomization.yaml`:
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
images:
|
images:
|
||||||
- name: ghcr.io/<owner>/bluecap-strategies-website
|
- name: 10.66.15.22:3000/bmr_bluecap/bcs-website
|
||||||
newTag: <ci-sets-this>
|
newTag: <ci-sets-this>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Option B: ArgoCD Image Updater
|
### Option B: ArgoCD Image Updater
|
||||||
Install ArgoCD Image Updater and annotate the Application to watch the GHCR repo and write back
|
Install ArgoCD Image Updater and annotate the Application to watch the Gitea Packages repo and write back
|
||||||
the tag. Removes the CI commit-back step but adds a controller and registry-credential wiring.
|
the tag. Removes the CI commit-back step but adds a controller and registry-credential wiring.
|
||||||
Only adopt if the homelab already runs Image Updater for other apps.
|
Only adopt if the homelab already runs Image Updater for other apps.
|
||||||
|
|
||||||
## Phase 2: CI Pipeline (GitHub Actions)
|
## Phase 2: CI Pipeline (Gitea Actions)
|
||||||
|
|
||||||
Workflow on push to `main`:
|
Workflow on push to `main`:
|
||||||
|
|
||||||
1. **Quality gate:** `npm ci`, `npm run typecheck`, `npm run build`.
|
1. **Quality gate:** `npm ci`, `npm run typecheck`, `npm run build`.
|
||||||
2. **E2E validation:** `npm run test:e2e` (Playwright) where browser deps are available.
|
2. **E2E validation:** `npm run test:e2e` (Playwright) where browser deps are available.
|
||||||
3. **Publish:** build the Docker image, push to GHCR tagged `<git-sha>`.
|
3. **Publish:** build the Docker image, push to Gitea Packages tagged `<git-sha>`.
|
||||||
4. **GitOps sync (Option A):** `kustomize edit set image ...=ghcr.io/<owner>/...:<git-sha>`,
|
4. **GitOps sync (Option A):** `kustomize edit set image ...=10.66.15.22:3000/bmr_bluecap/bcs-website:<git-sha>`,
|
||||||
commit and push to `main`. ArgoCD reconciles.
|
commit and push to `main`. ArgoCD reconciles.
|
||||||
|
|
||||||
CI never touches the cluster — it only writes to GHCR and Git.
|
CI never touches the cluster — it only writes to Gitea Packages and Git.
|
||||||
|
|
||||||
## Phase 3: Staging (Launch Readiness)
|
## Phase 3: Staging (Launch Readiness)
|
||||||
|
|
||||||
@ -139,7 +154,7 @@ Application tracking it.
|
|||||||
|
|
||||||
### 1. Secret hygiene — Git-managed credentials
|
### 1. Secret hygiene — Git-managed credentials
|
||||||
Avoid manual `kubectl create secret`. Use **Sealed Secrets** or **External Secrets Operator** so
|
Avoid manual `kubectl create secret`. Use **Sealed Secrets** or **External Secrets Operator** so
|
||||||
GHCR pull tokens and contact-form keys are encrypted in Git and the site is reproducible from
|
Gitea Packages pull tokens and contact-form keys are encrypted in Git and the site is reproducible from
|
||||||
source alone. Match whichever the homelab ArgoCD stack already standardizes on.
|
source alone. Match whichever the homelab ArgoCD stack already standardizes on.
|
||||||
|
|
||||||
### 2. Edge authority — Cloudflare hardening
|
### 2. Edge authority — Cloudflare hardening
|
||||||
|
|||||||
@ -13,9 +13,14 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app: bluecap-website
|
app: bluecap-website
|
||||||
spec:
|
spec:
|
||||||
|
# If the Gitea package is PRIVATE, create a docker-registry secret (ideally via
|
||||||
|
# External Secrets) named `gitea-registry` in this namespace and uncomment:
|
||||||
|
# imagePullSecrets:
|
||||||
|
# - name: gitea-registry
|
||||||
containers:
|
containers:
|
||||||
- name: website
|
- name: website
|
||||||
image: ghcr.io/your-org/bluecap-strategies-website:latest
|
# Tag is managed by CI via kustomize (see k8s/kustomization.yaml `images`).
|
||||||
|
image: 10.66.15.22:3000/bmr_bluecap/bcs-website:latest
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
|
|||||||
@ -6,3 +6,8 @@ resources:
|
|||||||
- deployment.yaml
|
- deployment.yaml
|
||||||
- service.yaml
|
- service.yaml
|
||||||
- ingress.yaml
|
- ingress.yaml
|
||||||
|
|
||||||
|
# CI updates newTag to the immutable git-sha via `kustomize edit set image` (see .gitea/workflows/ci.yml).
|
||||||
|
images:
|
||||||
|
- name: 10.66.15.22:3000/bmr_bluecap/bcs-website
|
||||||
|
newTag: latest
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user