# Spec: Migrate Workflows to GitHub Actions **Change**: 260406-vhk4-migrate-workflows-github-actions **Created**: 2026-04-06 **Affected memory**: None ## Non-Goals - Enabling Grype vulnerability scanning — intentionally left disabled - Modifying non-GCP workflows (`pr-lint-and-check.yml`, `push-code-test.yml`, `push-code-scan.yml`, `push-npm.yml`, `push-npm-from-container.yml`) - Changing the GCP authentication pattern (secrets/vars remain identical) - Updating consuming repos' `uses:` references (out of scope for this repo) ## Workflows: Archive Non-GCP Variants ### Requirement: Archive legacy workflows The system SHALL move the 4 non-GCP workflow files to `.github/workflows/archive/` to preserve history without cluttering the active workflows directory. Files to archive: - `.github/workflows/base-build-image.yml` - `.github/workflows/dispatch-container-base.yml` - `.github/workflows/push-container.yml` - `.github/workflows/push-s3.yml` #### Scenario: Archive directory creation and file move - **GIVEN** the 4 non-GCP workflow files exist in `.github/workflows/` - **WHEN** the migration is applied - **THEN** `.github/workflows/archive/` directory SHALL exist - **AND** all 4 files SHALL be moved to `.github/workflows/archive/` with identical filenames - **AND** the files SHALL no longer exist in `.github/workflows/` ## Workflows: Rename GCP Variants ### Requirement: Drop `-gcp` suffix from workflow filenames The system SHALL rename the 4 GCP workflow files to remove the `-gcp` suffix, making them the canonical workflow files. | Current name | New name | |---|---| | `base-build-image-gcp.yml` | `base-build-image.yml` | | `dispatch-container-base-gcp.yml` | `dispatch-container-base.yml` | | `push-container-gcp.yml` | `push-container.yml` | | `push-s3-gcp.yml` | `push-s3.yml` | #### Scenario: Rename after archive - **GIVEN** the non-GCP files have been archived (no naming collision) - **WHEN** the GCP files are renamed - **THEN** each `-gcp.yml` file SHALL be renamed to the corresponding base name - **AND** the original `-gcp.yml` files SHALL no longer exist - **AND** the file contents SHALL be unchanged (rename only, no content modification at this stage) ## Workflows: Fix S3 Upload Action ### Requirement: Replace Gitea-hosted aws-cli-action The `push-s3.yml` workflow (formerly `push-s3-gcp.yml`) SHALL replace the Gitea-hosted action reference with the `aws-actions/configure-aws-credentials@v4` action plus an inline `aws s3 cp` command, matching the pattern established in the `dg2n-core` repo. #### Scenario: AWS credentials configuration - **GIVEN** `push-s3.yml` has been renamed from `push-s3-gcp.yml` - **WHEN** the S3 upload steps are updated - **THEN** the `Upload cloud files` step using `https://git.gmetri.io/gmetribin/aws-cli-action@v1.0.0` SHALL be replaced with two steps: 1. A `Configure AWS credentials` step using `aws-actions/configure-aws-credentials@v4` with: - `aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}` - `aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}` - `aws-region: ${{ vars.AWS_DEFAULT_REGION }}` 2. An `Upload cloud files` step using `run:` with inline `aws s3 cp` command #### Scenario: AWS secret/var name casing - **GIVEN** the current workflow uses lowercase secret names (`secrets.aws_access_key_id`, etc.) - **WHEN** the S3 steps are replaced - **THEN** all AWS secret and variable references SHALL use uppercase names: - `secrets.AWS_ACCESS_KEY_ID` (was `secrets.aws_access_key_id`) - `secrets.AWS_SECRET_ACCESS_KEY` (was `secrets.aws_secret_access_key`) - `vars.AWS_DEFAULT_REGION` (was `vars.aws_default_region`) - `vars.AWS_UPLOAD_BUCKET` (was `vars.aws_upload_bucket`) #### Scenario: S3 upload command equivalence - **GIVEN** the old action ran `s3 cp --recursive --cache-control max-age=31536000 --storage-class 'STANDARD_IA' cloud/ s3://{bucket}/{repo}/{build_id}` - **WHEN** the inline command replaces it - **THEN** the `aws s3 cp` command SHALL preserve all flags: `--recursive`, `--cache-control max-age=31536000`, `--storage-class STANDARD_IA` - **AND** the destination path SHALL remain `s3://${{ vars.AWS_UPLOAD_BUCKET }}/${{ env.REPO_SHORT_NAME }}/${{ steps.get-id.outputs.BUILD_ID }}` ## Workflows: Preserve Existing Behavior ### Requirement: No functional changes to GCP auth All 4 renamed workflows SHALL retain their existing GCP authentication steps unchanged: - `google-github-actions/auth@v2` with `credentials_json: ${{ secrets.GCP_SA_KEY }}` - `google-github-actions/setup-gcloud@v2` with `project_id: ${{ vars.GCP_PROJECT_ID }}` - `gcloud auth configure-docker ${{ vars.GCP_REGION }}-docker.pkg.dev` #### Scenario: GCP auth preserved after rename - **GIVEN** any of the 4 renamed workflow files - **WHEN** the file content is inspected - **THEN** the GCP auth steps SHALL be identical to the original `-gcp` variant ### Requirement: Runners use GitHub-hosted ubuntu-22.04 All workflows SHALL use `runs-on: ubuntu-22.04` (GitHub-hosted runners). No self-hosted runner references. #### Scenario: Runner specification - **GIVEN** any workflow file in `.github/workflows/` (excluding archive) - **WHEN** the `runs-on` value is inspected - **THEN** it SHALL be `ubuntu-22.04` ### Requirement: Grype scanning remains disabled All workflows SHALL keep Grype vulnerability scanning commented out. No uncommented `anchore/scan-action` steps. #### Scenario: Grype stays commented - **GIVEN** any workflow that previously had Grype scanning commented out - **WHEN** the migration is complete - **THEN** the Grype scanning steps SHALL remain commented out ## Assumptions | # | Grade | Decision | Rationale | Scores | |---|-------|----------|-----------|--------| | 1 | Certain | Non-GCP workflows archived to `.github/workflows/archive/`, not deleted | Confirmed from intake #1 — user explicit | S:95 R:90 A:95 D:90 | | 2 | Certain | GCP workflows renamed to drop `-gcp` suffix | Confirmed from intake #2 — user explicit | S:95 R:85 A:90 D:85 | | 3 | Certain | Grype scanning stays disabled (commented out) | Confirmed from intake #3 — user explicit | S:95 R:90 A:95 D:95 | | 4 | Certain | Use `aws-actions/configure-aws-credentials@v4` + inline `aws s3 cp` | Confirmed from intake #4 — matches dg2n-core reference | S:95 R:90 A:90 D:85 | | 5 | Certain | AWS secret/var names uppercased to match dg2n-core | Confirmed from intake #5 — user said dg2n-core is correct | S:90 R:85 A:90 D:85 | | 6 | Certain | GitHub-hosted `ubuntu-22.04` runners | Confirmed from intake #6 — already the value in all workflows | S:95 R:90 A:95 D:90 | | 7 | Certain | S3 upload hybrid (GCP Docker + AWS S3) stays as-is | Confirmed from intake #7 — user explicit | S:90 R:85 A:90 D:90 | | 8 | Certain | Other 5 workflows unchanged | Upgraded from intake #8 Confident — user confirmed explicitly | S:90 R:85 A:90 D:85 | | 9 | Confident | Archive folder path is `.github/workflows/archive/` | Carried from intake #9 — user said "archive folder", path is reasonable convention | S:80 R:85 A:85 D:80 | | 10 | Certain | Archive must happen before rename to avoid filename collisions | Ordering constraint derived from spec — both old and new files share the same base names | S:95 R:95 A:95 D:95 | 10 assumptions (9 certain, 1 confident, 0 tentative, 0 unresolved).