diff --git a/.github/GITHUB_ACTIONS_MIGRATION.md b/.github/GITHUB_ACTIONS_MIGRATION.md new file mode 100644 index 000000000..116e90cb1 --- /dev/null +++ b/.github/GITHUB_ACTIONS_MIGRATION.md @@ -0,0 +1,167 @@ +# GitHub Actions Migration Guide + +This document describes the migration from GitLab CI to GitHub Actions for the Orbital project. + +## Overview + +The GitLab CI configuration has been migrated to GitHub Actions with the following workflow files: + +### Workflow Files + +1. **`ci.yml`** - Main CI/CD Pipeline + - Triggers: Push to all branches, tags, and pull requests + - Jobs: + - `verify-version`: Validates that tag versions match Maven POM version (tags only) + - `build-jvm`: Builds Java/Maven projects + - `build-orbital-ui`: Builds the Orbital UI + - `build-playground-ui`: Builds the Playground UI + - `publish-orbital`: Publishes Orbital Docker image (Alpine) + - `publish-orbital-jammy`: Publishes Orbital Docker image (Ubuntu Jammy) + - `publish-query-node`: Publishes Query Node Docker image + - `tag-as-latest`: Tags release images as 'latest' + +2. **`verify.yml`** - Verification and Security + - Triggers: Push to develop branch, manual dispatch + - Jobs: + - `scan-orbital`: Trivy container security scanning + - `validate-license-compliance`: License validation + - `regression-test`: Manual regression testing + +3. **`release.yml`** - Release Management + - Triggers: Manual workflow dispatch + - Jobs: + - `release`: Creates major/minor/patch releases using Maven gitflow plugin + +4. **`publish-core-types.yml`** - Publish Core Types + - Triggers: Push to develop, master, and tags + - Jobs: + - `publish-core-types`: Publishes core types to GitHub repository + +## Required Secrets + +The following secrets need to be configured in GitHub repository settings (Settings → Secrets and variables → Actions): + +### Required Secrets + +1. **`DOCKER_HUB_PASSWORD`** + - Description: Password for Docker Hub user 'vynecd' + - Used for: Publishing Docker images to Docker Hub + +2. **`GITHUB_PRIVATE_KEY`** + - Description: SSH private key for accessing orbital-core-taxi repository + - Used for: Publishing core types to GitHub + +### Optional Secrets + +These may be needed depending on your Maven repository configuration: + +- Maven repository credentials (if using private Maven repositories) +- Additional Docker registry credentials (if publishing to other registries) + +## Key Differences from GitLab CI + +### Branch Behavior + +| Branch/Tag | GitLab CI | GitHub Actions | +|------------|-----------|----------------| +| Feature branches | `build-jvm-branch` - clean install | Same - clean install | +| `develop` | `build-jvm-develop` - clean deploy with `-P snapshot-release` | Same behavior | +| `release/*` | Deploy with `-P snapshot-release` | Same behavior | +| Tags (`v*`) | `build-jvm-release` - deploy with `-P release` | Same behavior | + +### Docker Publishing + +- **GitLab**: Used `jdrouet/docker-with-buildx` image +- **GitHub Actions**: Uses official Docker actions (setup-qemu-action, setup-buildx-action, build-push-action) + +Docker tags follow the same pattern: +- `develop` → `next` and `next-{run_id}` +- `master` → `latest` and version +- Tags → tag name and tag name +- `release/*` → `{branch}-next` and `{version}-BETA-{run_id}` + +### Caching + +- **GitLab**: Explicit cache configuration for `.m2/repository` and `.npm/cache` +- **GitHub Actions**: Uses built-in cache actions (`actions/setup-java@v4` with `cache: maven`, `actions/setup-node@v4` with cache) + +### Artifacts + +- **GitLab**: 1-hour expiration for build artifacts +- **GitHub Actions**: 1-day retention for build artifacts, 7 days for test results + +## Manual Workflows + +### Creating a Release + +In GitLab CI, releases were triggered manually on the develop branch with buttons. In GitHub Actions: + +1. Go to Actions → Release workflow +2. Click "Run workflow" +3. Select branch: `develop` +4. Choose release type: `major`, `minor`, or `patch` +5. Click "Run workflow" + +### Running Regression Tests + +1. Go to Actions → Verify workflow +2. Click "Run workflow" +3. Select the branch you want to test +4. Click "Run workflow" + +## Workflow Triggers + +### Automatic Triggers + +- **All branches**: Build and test on every push +- **develop, master, release/*, tags**: Build, test, and publish Docker images +- **develop**: Container scanning and license validation + +### Manual Triggers + +- **Release workflow**: Manual dispatch for creating releases +- **Verify workflow**: Manual dispatch for running verification tasks +- **Regression tests**: Part of verify workflow, manual dispatch only + +## Migration Checklist + +- [ ] Configure `DOCKER_HUB_PASSWORD` secret in GitHub +- [ ] Configure `GITHUB_PRIVATE_KEY` secret in GitHub +- [ ] Verify Maven settings.xml is present at `.mvn/settings.xml` +- [ ] Test a feature branch build +- [ ] Test a develop branch build and Docker publish +- [ ] Verify container scanning works on develop +- [ ] Test manual release workflow (optional) +- [ ] Remove or archive `.gitlab-ci.yml` file + +## Notes + +1. **Multi-platform builds**: Both GitLab CI and GitHub Actions build for `linux/amd64` and `linux/arm64` platforms. + +2. **Test reruns**: The `MAVEN_OPTS` includes `-Dsurefire.rerunFailingTestsCount=2` to automatically retry failing tests. + +3. **Git depth**: Checkout uses `fetch-depth: 10` (same as GitLab's `GIT_DEPTH: 10`). + +4. **Build numbers**: Uses `${{ github.run_id }}` instead of GitLab's `$CI_PIPELINE_ID`. + +5. **Environment protection**: The `tag-as-latest` job could be protected with a GitHub environment for production deployments. + +## Troubleshooting + +### Docker build fails with authentication error +- Verify `DOCKER_HUB_PASSWORD` secret is correctly set +- Check that the password is for user 'vynecd' + +### Maven build fails with dependency resolution +- Check that `.mvn/settings.xml` exists and is correctly configured +- Verify Maven cache is being used (check workflow logs) + +### Publish core types fails +- Verify `GITHUB_PRIVATE_KEY` is correctly set +- Ensure the SSH key has access to the orbital-core-taxi repository +- Check that the key doesn't require a passphrase + +### Container scan fails +- This is expected if there are HIGH or CRITICAL vulnerabilities +- Review the scan results in the Security tab +- Update dependencies to resolve vulnerabilities diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..9a57c1fac --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,463 @@ +name: CI/CD Pipeline + +on: + push: + branches: + - '**' + tags: + - 'v*' + pull_request: + branches: + - develop + - master + +env: + MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true -Dsurefire.rerunFailingTestsCount=2 -Denv.buildServer=true" + MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DdeployAtEnd=true -Denv.buildServer=true -U --settings .mvn/settings.xml" + +jobs: + verify-version: + name: Verify Version (Tags Only) + runs-on: self-hosted + if: startsWith(github.ref, 'refs/tags/') + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + + - name: Verify tag matches Maven version + run: | + echo "Tag is: ${{ github.ref_name }}" + TAG_NO_V="${{ github.ref_name }}" + TAG_NO_V="${TAG_NO_V#v}" + + # Read Maven project.version + MVN_VER=$(mvn -q -DforceStdout -Dexpression=project.version help:evaluate | tail -n 1) + echo "Maven project.version is: $MVN_VER" + + # Forbid -SNAPSHOT on tags + if [[ "$MVN_VER" == *-SNAPSHOT ]]; then + echo "❌ project.version ends with -SNAPSHOT, but this is a tag build." + exit 1 + fi + + # Compare versions + if [[ "$MVN_VER" != "$TAG_NO_V" ]]; then + echo "❌ Version mismatch: tag '${{ github.ref_name }}' implies '$TAG_NO_V' but project.version is '$MVN_VER'." + exit 1 + else + echo "✅ Versions match." + fi + + + build-jvm: + name: Build JVM + runs-on: self-hosted + needs: verify-version + if: | + always() && + (needs.verify-version.result == 'success' || needs.verify-version.result == 'skipped') + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 10 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: 'maven' + + - name: Configure Docker authentication + run: | + mkdir -p /home/runner/.docker/ + cat > /home/runner/.docker/config.json << EOF + { + "auths": { + "https://index.docker.io/v1/": { + "username": "vynecd", + "password": "${{ secrets.DOCKER_HUB_PASSWORD }}", + "auth": "$(echo -n 'vynecd:${{ secrets.DOCKER_HUB_PASSWORD }}' | base64)" + } + } + } + EOF + + - name: Determine Maven goals + id: maven-config + run: | + if [[ "${{ github.ref }}" == refs/tags/* ]]; then + echo "goals=clean deploy" >> $GITHUB_OUTPUT + echo "extra_args=-P release -DskipTests" >> $GITHUB_OUTPUT + elif [[ "${{ github.ref_name }}" == "develop" ]] || [[ "${{ github.ref_name }}" == release/* ]]; then + echo "goals=clean deploy" >> $GITHUB_OUTPUT + echo "extra_args=-P snapshot-release -DskipTests" >> $GITHUB_OUTPUT + else + echo "goals=clean install" >> $GITHUB_OUTPUT + echo "extra_args=" >> $GITHUB_OUTPUT + fi + + - name: Build with Maven + env: + DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }} + JOOQ_REPO_USERNAME: ${{ secrets.JOOQ_REPO_USERNAME }} + JOOQ_REPO_PASSWORD: ${{ secrets.JOOQ_REPO_PASSWORD }} + run: | + echo "Running Maven with goals: ${{ steps.maven-config.outputs.goals }}" + mvn $MAVEN_CLI_OPTS -DbuildNumber=${{ github.run_id }} ${{ steps.maven-config.outputs.extra_args }} ${{ steps.maven-config.outputs.goals }} + + - name: Extract version from POM + run: | + mvn --non-recursive help:evaluate -Dexpression=project.version + mvn --non-recursive help:evaluate -Dexpression=project.version | grep -v '\[.*' > build-version.txt + echo "Build version: $(cat build-version.txt)" + + - name: Generate third-party licenses + run: mvn license:aggregate-add-third-party + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: build-artifacts + path: | + build-version.txt + target/generated-sources/license/THIRD-PARTY.txt + query-node-native/target/query-node-native.jar + station/target/orbital.zip + taxi-playground/target/taxi-playground.jar + retention-days: 1 + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-jvm + path: '**/target/surefire-reports/TEST-*.xml' + retention-days: 7 + if-no-files-found: ignore + + build-orbital-ui: + name: Build Orbital UI + runs-on: self-hosted + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'npm' + cache-dependency-path: orbital-ui/package-lock.json + + - name: Configure npm cache + run: | + npm config set cache .npm/cache --global + npm --global cache verify + + - name: Build UI + env: + NODE_OPTIONS: "--max-old-space-size=8192" + run: | + cd orbital-ui + npm ci + npm run-script build-prod + npx license-checker --out ../licenses.csv --csv + + - name: Upload UI artifacts + uses: actions/upload-artifact@v4 + with: + name: orbital-ui + path: | + station/target/classes/static + licenses.csv + retention-days: 1 + + build-playground-ui: + name: Build Playground UI + runs-on: self-hosted + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'npm' + cache-dependency-path: orbital-ui/package-lock.json + + - name: Configure npm cache + run: | + npm config set cache .npm/cache --global + npm --global cache verify + + - name: Build Playground UI + env: + NODE_OPTIONS: "--max-old-space-size=8192" + run: | + cd orbital-ui + npm ci + npm run-script build-prod-playground + + - name: Upload Playground UI artifacts + uses: actions/upload-artifact@v4 + with: + name: playground-ui + path: taxi-playground/target/classes/static + retention-days: 1 + + publish-orbital: + name: Publish Orbital (Alpine) + runs-on: ubuntu-latest + needs: build-jvm + if: | + github.event_name == 'push' && ( + github.ref == 'refs/heads/develop' || + github.ref == 'refs/heads/master' || + startsWith(github.ref, 'refs/tags/v') || + startsWith(github.ref, 'refs/heads/release/') + ) + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-artifacts + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: vynecd + password: ${{ secrets.DOCKER_HUB_PASSWORD }} + + - name: Determine Docker tags + id: docker-tags + run: | + PROJECT_VERSION=$(cat build-version.txt) + + if [[ "${{ github.ref }}" == refs/tags/* ]]; then + tag="${{ github.ref_name }}" + versionTag="${{ github.ref_name }}" + elif [[ "${{ github.ref_name }}" == "master" ]]; then + tag="latest" + versionTag="$PROJECT_VERSION" + elif [[ "${{ github.ref_name }}" == "develop" ]]; then + tag="next" + versionTag="next-${{ github.run_id }}" + elif [[ "${{ github.ref_name }}" == release/* ]]; then + stripped_branch=$(echo "${{ github.ref_name }}" | sed 's/release\///') + tag="$stripped_branch-next" + versionTag="$PROJECT_VERSION-BETA-${{ github.run_id }}" + else + tag="${{ github.ref_name }}-next" + versionTag="$PROJECT_VERSION-BETA-${{ github.run_id }}" + fi + + echo "tag=$tag" >> $GITHUB_OUTPUT + echo "version_tag=$versionTag" >> $GITHUB_OUTPUT + echo "Running on branch '${{ github.ref_name }}': tag = $tag" + echo "Running on branch '${{ github.ref_name }}': version = $versionTag" + + - name: Build and push Orbital Docker image + uses: docker/build-push-action@v5 + with: + context: ./station + platforms: linux/amd64,linux/arm64 + push: true + build-args: | + BASE_IMAGE_TAG=alpine + tags: | + orbitalhq/orbital:${{ steps.docker-tags.outputs.tag }} + orbitalhq/orbital:${{ steps.docker-tags.outputs.version_tag }} + + publish-orbital-jammy: + name: Publish Orbital (Ubuntu Jammy) + runs-on: ubuntu-latest + needs: build-jvm + if: | + github.event_name == 'push' && ( + github.ref == 'refs/heads/develop' || + github.ref == 'refs/heads/master' || + startsWith(github.ref, 'refs/tags/v') || + startsWith(github.ref, 'refs/heads/release/') + ) + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-artifacts + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: vynecd + password: ${{ secrets.DOCKER_HUB_PASSWORD }} + + - name: Determine Docker tags + id: docker-tags + run: | + PROJECT_VERSION=$(cat build-version.txt) + + if [[ "${{ github.ref }}" == refs/tags/* ]]; then + tag="${{ github.ref_name }}-jammy" + versionTag="${{ github.ref_name }}-jammy" + elif [[ "${{ github.ref_name }}" == "master" ]]; then + tag="latest-jammy" + versionTag="$PROJECT_VERSION-jammy" + elif [[ "${{ github.ref_name }}" == "develop" ]]; then + tag="next-jammy" + versionTag="next-${{ github.run_id }}-jammy" + elif [[ "${{ github.ref_name }}" == release/* ]]; then + stripped_branch=$(echo "${{ github.ref_name }}" | sed 's/release\///') + tag="$stripped_branch-next-jammy" + versionTag="$PROJECT_VERSION-BETA-${{ github.run_id }}-jammy" + else + tag="${{ github.ref_name }}-next-jammy" + versionTag="$PROJECT_VERSION-BETA-${{ github.run_id }}-jammy" + fi + + echo "tag=$tag" >> $GITHUB_OUTPUT + echo "version_tag=$versionTag" >> $GITHUB_OUTPUT + + - name: Build and push Orbital Docker image (Jammy) + uses: docker/build-push-action@v5 + with: + context: ./station + platforms: linux/amd64,linux/arm64 + push: true + build-args: | + BASE_IMAGE_TAG=jammy + tags: | + orbitalhq/orbital:${{ steps.docker-tags.outputs.tag }} + orbitalhq/orbital:${{ steps.docker-tags.outputs.version_tag }} + + publish-query-node: + name: Publish Query Node + runs-on: ubuntu-latest + needs: build-jvm + if: | + github.event_name == 'push' && ( + github.ref == 'refs/heads/develop' || + github.ref == 'refs/heads/master' || + startsWith(github.ref, 'refs/tags/v') || + startsWith(github.ref, 'refs/heads/release/') + ) + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-artifacts + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: vynecd + password: ${{ secrets.DOCKER_HUB_PASSWORD }} + + - name: Determine Docker tags + id: docker-tags + run: | + PROJECT_VERSION=$(cat build-version.txt) + + if [[ "${{ github.ref }}" == refs/tags/* ]]; then + tag="${{ github.ref_name }}" + versionTag="${{ github.ref_name }}" + elif [[ "${{ github.ref_name }}" == "master" ]]; then + tag="latest" + versionTag="$PROJECT_VERSION" + elif [[ "${{ github.ref_name }}" == "develop" ]]; then + tag="next" + versionTag="next-${{ github.run_id }}" + elif [[ "${{ github.ref_name }}" == release/* ]]; then + stripped_branch=$(echo "${{ github.ref_name }}" | sed 's/release\///') + tag="$stripped_branch-next" + versionTag="$PROJECT_VERSION-BETA-${{ github.run_id }}" + else + tag="${{ github.ref_name }}-next" + versionTag="$PROJECT_VERSION-BETA-${{ github.run_id }}" + fi + + echo "tag=$tag" >> $GITHUB_OUTPUT + echo "version_tag=$versionTag" >> $GITHUB_OUTPUT + + - name: Build and push Query Node Docker image + uses: docker/build-push-action@v5 + with: + context: ./query-node-native + platforms: linux/amd64,linux/arm64 + push: true + tags: | + orbitalhq/query-node:${{ steps.docker-tags.outputs.tag }} + orbitalhq/query-node:${{ steps.docker-tags.outputs.version_tag }} + + tag-as-latest: + name: Tag Images as Latest + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + needs: + - publish-orbital + - publish-orbital-jammy + - publish-query-node + + steps: + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: vynecd + password: ${{ secrets.DOCKER_HUB_PASSWORD }} + + - name: Tag Orbital images as latest + run: | + docker pull orbitalhq/orbital:${{ github.ref_name }} + docker tag orbitalhq/orbital:${{ github.ref_name }} orbitalhq/orbital:latest + docker push orbitalhq/orbital:latest + + docker pull orbitalhq/orbital:${{ github.ref_name }}-jammy + docker tag orbitalhq/orbital:${{ github.ref_name }}-jammy orbitalhq/orbital:latest-jammy + docker push orbitalhq/orbital:latest-jammy + + - name: Tag Query Node image as latest + run: | + docker pull orbitalhq/query-node:${{ github.ref_name }} + docker tag orbitalhq/query-node:${{ github.ref_name }} orbitalhq/query-node:latest + docker push orbitalhq/query-node:latest diff --git a/.github/workflows/publish-core-types.yml b/.github/workflows/publish-core-types.yml new file mode 100644 index 000000000..de18cda8c --- /dev/null +++ b/.github/workflows/publish-core-types.yml @@ -0,0 +1,71 @@ +name: Publish Core Types + +on: + push: + branches: + - develop + - master + tags: + - 'v*' + +env: + MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" + MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DdeployAtEnd=true -Denv.buildServer=true -U --settings .mvn/settings.xml" + +jobs: + publish-core-types: + name: Publish Core Types to GitHub + runs-on: self-hosted + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: 'maven' + + - name: Set up SSH + run: | + mkdir -p ~/.ssh + echo "${{ secrets.GITHUB_PRIVATE_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + eval $(ssh-agent -s) + ssh-add ~/.ssh/id_rsa + ssh-keyscan github.com >> ~/.ssh/known_hosts + + - name: Extract project version + id: version + run: | + mvn --non-recursive help:evaluate -Dexpression=project.version + mvn --non-recursive help:evaluate -Dexpression=project.version | grep -v '\[.*' > build-version.txt + PROJECT_VERSION=$(cat build-version.txt) + echo "version=$PROJECT_VERSION" >> $GITHUB_OUTPUT + echo "Project version: $PROJECT_VERSION" + + - name: Build orbital-taxi-publisher + run: | + mvn $MAVEN_CLI_OPTS -DbuildNumber=${{ github.run_id }} install -pl orbital-taxi-publisher -am -DskipTests + + - name: Unzip and prepare publisher + run: | + cd orbital-taxi-publisher/target + unzip packagePublisher.zip + cd packagePublisher + mkdir -p schema + + - name: Publish to GitHub + env: + SSH_AUTH_SOCK: /tmp/ssh_agent.sock + run: | + eval $(ssh-agent -s) + ssh-add ~/.ssh/id_rsa + cd orbital-taxi-publisher/target/packagePublisher + ./bin/packagePublisher \ + --output=./schema \ + --version=${{ steps.version.outputs.version }} \ + --remote-url=git@github.com:orbitalapi/orbital-core-taxi \ + --ssh-key=$HOME/.ssh/id_rsa diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..7f1563eb1 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,57 @@ +name: Release + +on: + workflow_dispatch: + inputs: + release_type: + description: 'Release type' + required: true + type: choice + options: + - major + - minor + - patch + +jobs: + release: + name: Create ${{ inputs.release_type }} release + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/develop' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: 'maven' + + - name: Configure Git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Determine version digit + id: version-digit + run: | + case "${{ inputs.release_type }}" in + major) + echo "digit=0" >> $GITHUB_OUTPUT + ;; + minor) + echo "digit=1" >> $GITHUB_OUTPUT + ;; + patch) + echo "digit=2" >> $GITHUB_OUTPUT + ;; + esac + + - name: Run gitflow release + run: | + mvn gitflow:release -B -DversionDigitToIncrement=${{ steps.version-digit.outputs.digit }} -DskipTestProject=true diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml new file mode 100644 index 000000000..c1d32d635 --- /dev/null +++ b/.github/workflows/verify.yml @@ -0,0 +1,99 @@ +name: Verify + +on: + push: + branches: + - develop + workflow_dispatch: + +jobs: + scan-orbital: + name: Container Scan - Orbital + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/develop' + + steps: + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: 'orbitalhq/orbital:next' + format: 'sarif' + output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' + exit-code: '1' + + - name: Upload Trivy results to GitHub Security + uses: github/codeql-action/upload-sarif@v3 + if: always() + with: + sarif_file: 'trivy-results.sarif' + + - name: Run detailed Trivy scan + uses: aquasecurity/trivy-action@master + with: + image-ref: 'orbitalhq/orbital:next' + format: 'table' + output: 'vulnerabilities.txt' + severity: 'HIGH,CRITICAL' + + - name: Upload vulnerability report + uses: actions/upload-artifact@v4 + if: always() + with: + name: vulnerability-report-orbital + path: vulnerabilities.txt + retention-days: 30 + + validate-license-compliance: + name: Validate License Compliance + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download UI artifacts + uses: actions/download-artifact@v4 + with: + name: orbital-ui + continue-on-error: true + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Validate licenses + run: node processLicenses.js + + regression-test: + name: Regression Tests + runs-on: ubuntu-latest + if: github.event_name == 'workflow_dispatch' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: 'maven' + + - name: Build project + run: mvn clean install -DskipTests -Dskip.npm + + - name: Run regression tests + run: | + cd regression-tests + mvn -Dtest=TaxonomyRegressionTest -Drun.mode=docker -Dvyne.tag=latest test + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: regression-test-results + path: regression-tests/target/surefire-reports/TEST-*.xml + retention-days: 7