Merge branch 'feature/beta-release' into renovate/feature/beta-release-pin-dependencies
This commit is contained in:
15
.github/workflows/playwright.yml
vendored
15
.github/workflows/playwright.yml
vendored
@@ -84,6 +84,16 @@ jobs:
|
||||
echo "is_push=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Sanitize branch name
|
||||
id: sanitize
|
||||
run: |
|
||||
# Sanitize branch name for use in Docker tags and artifact names
|
||||
# Replace / with - to avoid invalid reference format errors
|
||||
BRANCH="${{ github.event.workflow_run.head_branch || github.head_ref || github.ref_name }}"
|
||||
SANITIZED=$(echo "$BRANCH" | tr '/' '-')
|
||||
echo "branch=${SANITIZED}" >> "$GITHUB_OUTPUT"
|
||||
echo "📋 Sanitized branch name: ${BRANCH} -> ${SANITIZED}"
|
||||
|
||||
- name: Check for PR image artifact
|
||||
id: check-artifact
|
||||
if: steps.pr-info.outputs.pr_number != '' || steps.pr-info.outputs.is_push == 'true'
|
||||
@@ -170,7 +180,8 @@ jobs:
|
||||
# Normalize image name (GitHub lowercases repository owner names in GHCR)
|
||||
IMAGE_NAME=$(echo "${{ github.repository_owner }}/charon" | tr '[:upper:]' '[:lower:]')
|
||||
if [[ "${{ steps.pr-info.outputs.is_push }}" == "true" ]]; then
|
||||
IMAGE_REF="ghcr.io/${IMAGE_NAME}:${{ github.event.workflow_run.head_branch }}"
|
||||
# Use sanitized branch name for Docker tag (/ is invalid in tags)
|
||||
IMAGE_REF="ghcr.io/${IMAGE_NAME}:${{ steps.sanitize.outputs.branch }}"
|
||||
else
|
||||
IMAGE_REF="ghcr.io/${IMAGE_NAME}:pr-${{ steps.pr-info.outputs.pr_number }}"
|
||||
fi
|
||||
@@ -237,7 +248,7 @@ jobs:
|
||||
# actions/upload-artifact v4.4.3
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
|
||||
with:
|
||||
name: ${{ steps.pr-info.outputs.is_push == 'true' && format('playwright-report-{0}', github.event.workflow_run.head_branch) || format('playwright-report-pr-{0}', steps.pr-info.outputs.pr_number) }}
|
||||
name: ${{ steps.pr-info.outputs.is_push == 'true' && format('playwright-report-{0}', steps.sanitize.outputs.branch) || format('playwright-report-pr-{0}', steps.pr-info.outputs.pr_number) }}
|
||||
path: playwright-report/
|
||||
retention-days: 14
|
||||
|
||||
|
||||
12
.github/workflows/supply-chain-pr.yml
vendored
12
.github/workflows/supply-chain-pr.yml
vendored
@@ -105,6 +105,16 @@ jobs:
|
||||
echo "is_push=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Sanitize branch name
|
||||
id: sanitize
|
||||
run: |
|
||||
# Sanitize branch name for use in artifact names
|
||||
# Replace / with - to avoid invalid reference format errors
|
||||
BRANCH="${{ github.event.workflow_run.head_branch || github.head_ref || github.ref_name }}"
|
||||
SANITIZED=$(echo "$BRANCH" | tr '/' '-')
|
||||
echo "branch=${SANITIZED}" >> "$GITHUB_OUTPUT"
|
||||
echo "📋 Sanitized branch name: ${BRANCH} -> ${SANITIZED}"
|
||||
|
||||
- name: Check for PR image artifact
|
||||
id: check-artifact
|
||||
if: steps.pr-number.outputs.pr_number != '' || steps.pr-number.outputs.is_push == 'true'
|
||||
@@ -297,7 +307,7 @@ jobs:
|
||||
# actions/upload-artifact v4.6.0
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
|
||||
with:
|
||||
name: ${{ steps.pr-number.outputs.is_push == 'true' && format('supply-chain-{0}', github.event.workflow_run.head_branch) || format('supply-chain-pr-{0}', steps.pr-number.outputs.pr_number) }}
|
||||
name: ${{ steps.pr-number.outputs.is_push == 'true' && format('supply-chain-{0}', steps.sanitize.outputs.branch) || format('supply-chain-pr-{0}', steps.pr-number.outputs.pr_number) }}
|
||||
path: |
|
||||
sbom.cyclonedx.json
|
||||
grype-results.json
|
||||
|
||||
13
.github/workflows/supply-chain-verify.yml
vendored
13
.github/workflows/supply-chain-verify.yml
vendored
@@ -71,15 +71,14 @@ jobs:
|
||||
if [[ "${{ github.event_name }}" == "release" ]]; then
|
||||
TAG="${{ github.event.release.tag_name }}"
|
||||
elif [[ "${{ github.event_name }}" == "workflow_run" ]]; then
|
||||
BRANCH="${{ github.event.workflow_run.head_branch }}"
|
||||
# Extract tag from the workflow that triggered us
|
||||
if [[ "${{ github.event.workflow_run.head_branch }}" == "main" ]]; then
|
||||
if [[ "${BRANCH}" == "main" ]]; then
|
||||
TAG="latest"
|
||||
elif [[ "${{ github.event.workflow_run.head_branch }}" == "development" ]]; then
|
||||
elif [[ "${BRANCH}" == "development" ]]; then
|
||||
TAG="dev"
|
||||
elif [[ "${{ github.event.workflow_run.head_branch }}" == "nightly" ]]; then
|
||||
elif [[ "${BRANCH}" == "nightly" ]]; then
|
||||
TAG="nightly"
|
||||
elif [[ "${{ github.event.workflow_run.head_branch }}" == "feature/beta-release" ]]; then
|
||||
TAG="beta"
|
||||
elif [[ "${{ github.event.workflow_run.event }}" == "pull_request" ]]; then
|
||||
# Extract PR number from workflow_run context with null handling
|
||||
PR_NUMBER=$(jq -r '.pull_requests[0].number // empty' <<< '${{ toJson(github.event.workflow_run.pull_requests) }}')
|
||||
@@ -90,7 +89,9 @@ jobs:
|
||||
TAG="sha-$(echo ${{ github.event.workflow_run.head_sha }} | cut -c1-7)"
|
||||
fi
|
||||
else
|
||||
TAG="sha-$(echo ${{ github.event.workflow_run.head_sha }} | cut -c1-7)"
|
||||
# For feature branches and other pushes, sanitize branch name for Docker tag
|
||||
# Replace / with - to avoid invalid reference format errors
|
||||
TAG=$(echo "${BRANCH}" | tr '/' '-')
|
||||
fi
|
||||
else
|
||||
TAG="latest"
|
||||
|
||||
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Fixed
|
||||
|
||||
- **GitHub Actions workflows failing with 'invalid reference format' for feature branches containing slashes**: Branch names like `feature/beta-release` now properly sanitized (replacing `/` with `-`) in Docker image tags and artifact names across `playwright.yml`, `supply-chain-verify.yml`, and `supply-chain-pr.yml` workflows
|
||||
- **PermissionsModal State Synchronization**: Fixed React anti-pattern where `useState` was used like `useEffect`, causing potential stale state when editing different users' permissions
|
||||
|
||||
### Added
|
||||
|
||||
@@ -1,7 +1,258 @@
|
||||
# WAF Integration Workflow Fix: wget-style curl Syntax Migration
|
||||
# WAF-2026-002: Docker Tag Sanitization for Branch Names
|
||||
|
||||
**Plan ID**: WAF-2026-002
|
||||
**Status**: ✅ COMPLETED
|
||||
**Priority**: High
|
||||
**Created**: 2026-01-25
|
||||
**Completed**: 2026-01-25
|
||||
**Scope**: Fix Docker image tag construction to handle branch names containing forward slashes
|
||||
|
||||
---
|
||||
|
||||
## Problem Summary
|
||||
|
||||
GitHub Actions workflows are failing with "invalid reference format" errors when building/pulling Docker images for feature branches. The root cause is that branch names like `feature/beta-release` contain forward slashes (`/`), which are **invalid characters in Docker image tags**.
|
||||
|
||||
### Docker Tag Naming Rules
|
||||
|
||||
Docker image tags must match the regex: `[a-zA-Z0-9_][a-zA-Z0-9._-]{0,127}`
|
||||
|
||||
Invalid characters include:
|
||||
- Forward slash (`/`) - **causes "invalid reference format" error**
|
||||
- Colon (`:`) - reserved for tag separator
|
||||
- Spaces and special characters
|
||||
|
||||
---
|
||||
|
||||
## Files Affected
|
||||
|
||||
### 1. `.github/workflows/playwright.yml` (Line 103)
|
||||
|
||||
**Location**: [playwright.yml](.github/workflows/playwright.yml#L103)
|
||||
|
||||
**Current (broken):**
|
||||
```yaml
|
||||
- name: Start Charon container
|
||||
run: |
|
||||
...
|
||||
if [[ "${{ steps.pr-info.outputs.is_push }}" == "true" ]]; then
|
||||
IMAGE_REF="ghcr.io/${IMAGE_NAME}:${{ github.event.workflow_run.head_branch }}"
|
||||
else
|
||||
```
|
||||
|
||||
**Issue**: `github.event.workflow_run.head_branch` can contain `/` (e.g., `feature/beta-release`)
|
||||
|
||||
**Fix:**
|
||||
```yaml
|
||||
- name: Start Charon container
|
||||
run: |
|
||||
...
|
||||
if [[ "${{ steps.pr-info.outputs.is_push }}" == "true" ]]; then
|
||||
# Sanitize branch name: replace / with -
|
||||
SANITIZED_BRANCH=$(echo "${{ github.event.workflow_run.head_branch }}" | tr '/' '-')
|
||||
IMAGE_REF="ghcr.io/${IMAGE_NAME}:${SANITIZED_BRANCH}"
|
||||
else
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. `.github/workflows/playwright.yml` (Line 161) - Artifact Naming
|
||||
|
||||
**Location**: [playwright.yml](.github/workflows/playwright.yml#L161)
|
||||
|
||||
**Current:**
|
||||
```yaml
|
||||
- name: Upload Playwright report
|
||||
uses: actions/upload-artifact@...
|
||||
with:
|
||||
name: ${{ steps.pr-info.outputs.is_push == 'true' && format('playwright-report-{0}', github.event.workflow_run.head_branch) || format('playwright-report-pr-{0}', steps.pr-info.outputs.pr_number) }}
|
||||
```
|
||||
|
||||
**Issue**: Artifact names also cannot contain `/`
|
||||
|
||||
**Fix:**
|
||||
Add a step to sanitize the branch name first and use an environment variable:
|
||||
```yaml
|
||||
- name: Sanitize branch name for artifact
|
||||
id: sanitize
|
||||
run: |
|
||||
SANITIZED=$(echo "${{ github.event.workflow_run.head_branch }}" | tr '/' '-')
|
||||
echo "branch=${SANITIZED}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload Playwright report
|
||||
uses: actions/upload-artifact@...
|
||||
with:
|
||||
name: ${{ steps.pr-info.outputs.is_push == 'true' && format('playwright-report-{0}', steps.sanitize.outputs.branch) || format('playwright-report-pr-{0}', steps.pr-info.outputs.pr_number) }}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. `.github/workflows/supply-chain-verify.yml` (Lines 64-90) - Tag Determination
|
||||
|
||||
**Location**: [supply-chain-verify.yml](.github/workflows/supply-chain-verify.yml#L64-L90)
|
||||
|
||||
**Current (partial):**
|
||||
```yaml
|
||||
- name: Determine Image Tag
|
||||
id: tag
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "release" ]]; then
|
||||
TAG="${{ github.event.release.tag_name }}"
|
||||
elif [[ "${{ github.event_name }}" == "workflow_run" ]]; then
|
||||
if [[ "${{ github.event.workflow_run.head_branch }}" == "main" ]]; then
|
||||
TAG="latest"
|
||||
elif [[ "${{ github.event.workflow_run.head_branch }}" == "development" ]]; then
|
||||
TAG="dev"
|
||||
elif [[ "${{ github.event.workflow_run.head_branch }}" == "nightly" ]]; then
|
||||
TAG="nightly"
|
||||
elif [[ "${{ github.event.workflow_run.head_branch }}" == "feature/beta-release" ]]; then
|
||||
TAG="beta"
|
||||
elif [[ "${{ github.event.workflow_run.event }}" == "pull_request" ]]; then
|
||||
...
|
||||
else
|
||||
TAG="sha-$(echo ${{ github.event.workflow_run.head_sha }} | cut -c1-7)"
|
||||
fi
|
||||
```
|
||||
|
||||
**Issue**: Only `feature/beta-release` is explicitly mapped. Other feature branches fall through to SHA-based tags which works, BUT there's an implicit assumption that docker-build.yml creates tags that match. The docker-build.yml uses `type=ref,event=branch` which DOES sanitize branch names.
|
||||
|
||||
**Analysis**: The logic here is complex. The `docker/metadata-action` in docker-build.yml uses:
|
||||
```yaml
|
||||
type=ref,event=branch,enable=${{ startsWith(github.ref, 'refs/heads/feature/') }}
|
||||
```
|
||||
|
||||
According to [docker/metadata-action docs](https://github.com/docker/metadata-action#typeref), `type=ref,event=branch` produces a tag like `feature-beta-release` (slashes replaced with dashes).
|
||||
|
||||
**Fix**: Align supply-chain-verify.yml with docker-build.yml's tag sanitization:
|
||||
```yaml
|
||||
- name: Determine Image Tag
|
||||
id: tag
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "release" ]]; then
|
||||
TAG="${{ github.event.release.tag_name }}"
|
||||
elif [[ "${{ github.event_name }}" == "workflow_run" ]]; then
|
||||
BRANCH="${{ github.event.workflow_run.head_branch }}"
|
||||
if [[ "${BRANCH}" == "main" ]]; then
|
||||
TAG="latest"
|
||||
elif [[ "${BRANCH}" == "development" ]]; then
|
||||
TAG="dev"
|
||||
elif [[ "${BRANCH}" == "nightly" ]]; then
|
||||
TAG="nightly"
|
||||
elif [[ "${BRANCH}" == feature/* ]]; then
|
||||
# Match docker/metadata-action behavior: type=ref,event=branch replaces / with -
|
||||
TAG=$(echo "${BRANCH}" | tr '/' '-')
|
||||
elif [[ "${{ github.event.workflow_run.event }}" == "pull_request" ]]; then
|
||||
...
|
||||
else
|
||||
TAG="sha-$(echo ${{ github.event.workflow_run.head_sha }} | cut -c1-7)"
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. `.github/workflows/supply-chain-pr.yml` (Line 196) - Artifact Naming
|
||||
|
||||
**Location**: [supply-chain-pr.yml](.github/workflows/supply-chain-pr.yml#L196)
|
||||
|
||||
**Current:**
|
||||
```yaml
|
||||
- name: Upload supply chain artifacts
|
||||
uses: actions/upload-artifact@...
|
||||
with:
|
||||
name: ${{ steps.pr-number.outputs.is_push == 'true' && format('supply-chain-{0}', github.event.workflow_run.head_branch) || format('supply-chain-pr-{0}', steps.pr-number.outputs.pr_number) }}
|
||||
```
|
||||
|
||||
**Issue**: Same artifact naming issue with unsanitized branch names
|
||||
|
||||
**Fix:**
|
||||
```yaml
|
||||
- name: Sanitize branch name
|
||||
id: sanitize
|
||||
if: steps.pr-number.outputs.is_push == 'true'
|
||||
run: |
|
||||
SANITIZED=$(echo "${{ github.event.workflow_run.head_branch }}" | tr '/' '-')
|
||||
echo "branch=${SANITIZED}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload supply chain artifacts
|
||||
uses: actions/upload-artifact@...
|
||||
with:
|
||||
name: ${{ steps.pr-number.outputs.is_push == 'true' && format('supply-chain-{0}', steps.sanitize.outputs.branch) || format('supply-chain-pr-{0}', steps.pr-number.outputs.pr_number) }}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## How docker/metadata-action Handles This
|
||||
|
||||
The `docker/metadata-action` correctly handles this via `type=ref,event=branch`:
|
||||
|
||||
From [docker-build.yml](.github/workflows/docker-build.yml#L89-L95):
|
||||
```yaml
|
||||
- name: Extract metadata (tags, labels)
|
||||
id: meta
|
||||
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
...
|
||||
type=ref,event=branch,enable=${{ startsWith(github.ref, 'refs/heads/feature/') }}
|
||||
```
|
||||
|
||||
The `type=ref,event=branch` option automatically sanitizes the branch name, replacing `/` with `-`.
|
||||
|
||||
**Result**: Feature branch `feature/beta-release` produces tag `feature-beta-release`
|
||||
|
||||
---
|
||||
|
||||
## Summary Table
|
||||
|
||||
| Workflow | Line | Issue | Fix Strategy |
|
||||
|----------|------|-------|--------------|
|
||||
| [playwright.yml](.github/workflows/playwright.yml) | 103 | `head_branch` used directly as tag | `tr '/' '-'` sanitization |
|
||||
| [playwright.yml](.github/workflows/playwright.yml) | 161 | `head_branch` in artifact name | Add sanitize step |
|
||||
| [supply-chain-verify.yml](.github/workflows/supply-chain-verify.yml) | 74 | Only hardcodes `feature/beta-release` | Generic feature/* handling with `tr '/' '-'` |
|
||||
| [supply-chain-pr.yml](.github/workflows/supply-chain-pr.yml) | 196 | `head_branch` in artifact name | Add sanitize step |
|
||||
|
||||
---
|
||||
|
||||
## Execution Checklist
|
||||
|
||||
- [ ] **Fix 1**: Update `playwright.yml` line 103 - sanitize branch name for Docker tag
|
||||
- [ ] **Fix 2**: Update `playwright.yml` line 161 - sanitize branch name for artifact
|
||||
- [ ] **Fix 3**: Update `supply-chain-verify.yml` lines 74-75 - generic feature branch handling
|
||||
- [ ] **Fix 4**: Update `supply-chain-pr.yml` line 196 - sanitize branch name for artifact
|
||||
- [ ] **Verify**: Push to `feature/beta-release` and confirm workflows pass
|
||||
- [ ] **CI**: All affected workflows should complete without "invalid reference format"
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
|
||||
After applying fixes:
|
||||
|
||||
```bash
|
||||
# Test sanitization logic locally
|
||||
echo "feature/beta-release" | tr '/' '-'
|
||||
# Expected output: feature-beta-release
|
||||
|
||||
# Verify Docker accepts the sanitized tag
|
||||
docker pull ghcr.io/owner/charon:feature-beta-release
|
||||
# Should work (or fail with 404 if not published yet, but NOT "invalid reference format")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Docker tag naming rules](https://docs.docker.com/engine/reference/commandline/tag/)
|
||||
- [docker/metadata-action type=ref behavior](https://github.com/docker/metadata-action#typeref)
|
||||
- GitHub Issue: Workflow failures on `feature/beta-release` branch
|
||||
|
||||
---
|
||||
|
||||
# WAF-2026-001: wget-style curl Syntax Migration (Archived)
|
||||
|
||||
**Plan ID**: WAF-2026-001
|
||||
**Status**: 📋 PENDING
|
||||
**Status**: ✅ ARCHIVED (Superseded by WAF-2026-002 as current active plan)
|
||||
**Priority**: High
|
||||
**Created**: 2026-01-25
|
||||
**Scope**: Fix integration test scripts using incorrect wget-style curl syntax
|
||||
|
||||
Reference in New Issue
Block a user