Skip to content

Commit dc01fad

Browse files
committed
feat(init): adds initial gitlab workflows
1 parent 731e36e commit dc01fad

12 files changed

Lines changed: 596 additions & 2 deletions

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Shell scripts always LF
2+
*.sh text eol=lf
3+
* text=auto eol=lf
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
on:
2+
workflow_call:
3+
4+
jobs:
5+
check-single-commit:
6+
name: Check Single Commit
7+
runs-on: ubuntu-latest
8+
timeout-minutes: 5
9+
steps:
10+
- name: Check number of commits in PR
11+
uses: actions/github-script@v8
12+
with:
13+
github-token: ${{ secrets.GITHUB_TOKEN }}
14+
script: |
15+
const pr = context.payload.pull_request;
16+
if (!pr && !(github.head_ref == 'develop' && github.base_ref == 'main')) {
17+
console.log("Not a pull request event. Skipping commit check.");
18+
return;
19+
}
20+
const commits = await github.rest.pulls.listCommits({
21+
owner: context.repo.owner,
22+
repo: context.repo.repo,
23+
pull_number: pr.number,
24+
});
25+
const count = commits.data.length;
26+
if (count > 1) {
27+
core.setFailed(`PR has ${count} commits. Please squash to a single commit.`);
28+
} else {
29+
console.log("PR has a single commit. ✅");
30+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
on:
2+
workflow_call:
3+
inputs:
4+
version:
5+
required: true
6+
type: string
7+
description: "Version of the application being deployed, used for versioned S3 paths and cache invalidation"
8+
environment:
9+
type: string
10+
required: true
11+
description: "environment to deploy to, used for selecting correct AWS credentials and CloudFront distribution based on environment specific secrets and variables"
12+
secrets:
13+
AWS_OIDC_ROLE_ARN:
14+
description: "OIDC role ARN for AWS credentials"
15+
required: true
16+
AWS_DEPLOYMENT_ROLE_ARN:
17+
description: "Deployment role ARN for AWS credentials"
18+
required: true
19+
20+
jobs:
21+
# todo push to versioned s3 path / dont invalidate cache / instead create PR on Infrastructure repo to update origin path or copy the directory
22+
build-push-s3:
23+
name: Build and push application to S3 bucket
24+
runs-on: ubuntu-latest
25+
environment: ${{ inputs.environment }}
26+
timeout-minutes: 5
27+
# todo activate once requried
28+
#FONTAWESOME_PACKAGE_TOKEN: ${{ secrets.FONTAWESOME_PACKAGE_TOKEN }}
29+
permissions:
30+
id-token: write
31+
contents: read
32+
steps:
33+
- name: Print GitHub Context Safely
34+
run: |
35+
echo "--- GitHub Context ---"
36+
echo "${GITHUB_REPOSITORY}"
37+
echo "${GITHUB_REF}"
38+
echo "${GITHUB_SHA}"
39+
40+
- name: Checkout
41+
uses: actions/checkout@v6
42+
with:
43+
ref: ${{ format('v{0}', inputs.version) }}
44+
45+
- name: Set up pnpm
46+
uses: pnpm/action-setup@v4
47+
48+
- name: Set up Node.js
49+
uses: actions/setup-node@v6
50+
with:
51+
node-version: 24
52+
cache: pnpm
53+
cache-dependency-path: pnpm-lock.yaml
54+
55+
- name: pnpm install
56+
run: pnpm install --frozen-lockfile --ignore-scripts
57+
58+
- name: Build
59+
# todo maybe adjust with env specific config eg: pnpm build -- --configuration=${{ steps.resolve-inputs.outputs.configuration }}
60+
run: pnpm build
61+
62+
- name: Configure AWS credentials (OIDC)
63+
uses: aws-actions/configure-aws-credentials@v4
64+
with:
65+
role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }}
66+
aws-region: ${{ vars.AWS_REGION }}
67+
68+
- name: Assume deployment role
69+
uses: aws-actions/configure-aws-credentials@v4
70+
with:
71+
role-to-assume: ${{ secrets.AWS_DEPLOYMENT_ROLE_ARN }}
72+
aws-region: ${{ vars.AWS_REGION }}
73+
role-chaining: true
74+
role-skip-session-tagging: true
75+
76+
- name: Deploy to S3 bucket
77+
env:
78+
VERSION: ${{ inputs.version }}
79+
run: |
80+
set -euo pipefail
81+
82+
# Allowlist validation (adjust to your conventions)
83+
[[ "$VERSION" =~ ^[0-9]+(\.[0-9]+){2}([.-][0-9A-Za-z]+)*$ ]] || { echo "Invalid version"; exit 1; }
84+
85+
86+
echo "Deploying version: v${VERSION}"
87+
88+
aws s3 sync "dist/atlas-agate-frontend/browser/" "s3://${{vars.FRONTEND_S3_BUCKET}}/" \
89+
--region "$AWS_REGION" \
90+
--delete
91+
92+
- name: Invalidate CloudFront cache
93+
run: |
94+
echo "Creating CloudFront invalidation for distribution: ${{ vars.CLOUDFRONT_DISTRIBUTION_ID }}"
95+
aws cloudfront create-invalidation \
96+
--distribution-id ${{ vars.CLOUDFRONT_DISTRIBUTION_ID }} \
97+
--paths "/*"
98+
99+
- name: Display deployment URL
100+
run: |
101+
echo "✅ Deployment complete!"
102+
echo "🌐 Your application is available at: https://www.blw-agate-dev.pc-core.isceco.admin.ch"
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
on:
2+
workflow_call:
3+
secrets:
4+
SONAR_TOKEN:
5+
description: "SonarQube authentication token"
6+
required: true
7+
jobs:
8+
unit-test-sonarqube:
9+
name: Unit Tests and SonarQube
10+
runs-on: ubuntu-latest
11+
timeout-minutes: 10
12+
env:
13+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
14+
#env:
15+
#todo activate once needed
16+
#FONTAWESOME_PACKAGE_TOKEN: ${{ secrets.FONTAWESOME_PACKAGE_TOKEN }}
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v6
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Set up pnpm
24+
uses: pnpm/action-setup@v4
25+
26+
- name: Set up Node.js
27+
uses: actions/setup-node@v6
28+
with:
29+
node-version: 24
30+
cache: pnpm
31+
cache-dependency-path: pnpm-lock.yaml
32+
33+
- name: Install dependencies
34+
run: pnpm install --frozen-lockfile --ignore-scripts
35+
36+
- name: Lint
37+
run: pnpm lint
38+
39+
- name: Run unit tests
40+
run: pnpm test
41+
42+
- name: Run SonarQube Analysis
43+
uses: SonarSource/sonarqube-scan-action@v7
44+
env:
45+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
46+
with:
47+
projectBaseDir: .
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
name: "frontend workflow"
2+
3+
permissions:
4+
contents: write
5+
pull-requests: write
6+
id-token: write
7+
issues: write
8+
9+
on:
10+
workflow_call:
11+
inputs:
12+
app-id:
13+
description: "GitHub App ID used for downstream workflows"
14+
required: true
15+
type: string
16+
secrets:
17+
GH_ORG_PRIVATE_KEY:
18+
description: "GitHub App private key used for downstream workflows"
19+
required: true
20+
GH_ORG_GITLEAKS_PRIVATE_KEY:
21+
description: "GitHub App private key used for gitleaks token"
22+
required: true
23+
LICENSE_KEY_GITLEAKS:
24+
description: "Gitleaks license key"
25+
required: true
26+
SONAR_TOKEN:
27+
description: "SonarQube authentication token"
28+
required: true
29+
AWS_OIDC_ROLE_ARN:
30+
description: "OIDC role ARN for AWS credentials"
31+
required: true
32+
AWS_DEPLOYMENT_ROLE_ARN:
33+
description: "Deployment role ARN for AWS credentials"
34+
required: true
35+
36+
jobs:
37+
check-single-commit:
38+
name: '.'
39+
uses: ./.github/workflows/check_single_commit.yml
40+
41+
gitleaks:
42+
name: '.'
43+
uses: ./.github/workflows/gitleaks.yml
44+
needs: check-single-commit
45+
secrets:
46+
GH_ORG_GITLEAKS_PRIVATE_KEY: ${{ secrets.GH_ORG_GITLEAKS_PRIVATE_KEY }}
47+
LICENSE_KEY_GITLEAKS: ${{ secrets.LICENSE_KEY_GITLEAKS }}
48+
49+
vulnerability-scan:
50+
name: '.'
51+
uses: ./.github/workflows/vulnrability_scan.yml
52+
needs: [ check-single-commit ]
53+
54+
unit-test-sonarqube:
55+
name: '.'
56+
uses: frontend_unit_test_sonarqube.yml
57+
needs: [ vulnerability-scan, gitleaks ]
58+
secrets:
59+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
60+
61+
semantic-release:
62+
name: '.'
63+
if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') }}
64+
uses: ./.github/workflows/semantic_release.yml
65+
needs: [unit-test-sonarqube, vulnerability-scan]
66+
secrets:
67+
GH_ORG_PRIVATE_KEY: ${{ secrets.GH_ORG_PRIVATE_KEY }}
68+
with:
69+
app-id: ${{ inputs.app-id }}
70+
71+
build-and-push:
72+
name: '.'
73+
if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') }}
74+
uses: ./.github/workflows/frontend_build_deploy_s3.yml
75+
needs: [semantic-release ]
76+
secrets:
77+
AWS_OIDC_ROLE_ARN: ${{ secrets.AWS_OIDC_ROLE_ARN }}
78+
AWS_DEPLOYMENT_ROLE_ARN: ${{ secrets.AWS_DEPLOYMENT_ROLE_ARN }}
79+
with:
80+
version: ${{ needs.semantic-release.outputs.version }}
81+
environment: ${{ github.ref == 'refs/heads/develop' && 'develop' || 'integration' }}
82+
83+
merge-main-develop:
84+
name: '.'
85+
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
86+
uses: ./.github/workflows/merge_main_develop.yml
87+
needs: [ semantic-release ]
88+
secrets:
89+
GH_ORG_PRIVATE_KEY: ${{ secrets.GH_ORG_PRIVATE_KEY }}

.github/workflows/gitleaks.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
on:
2+
workflow_call:
3+
secrets:
4+
GH_ORG_GITLEAKS_PRIVATE_KEY:
5+
description: "GitHub App private key used for gitleaks token"
6+
required: true
7+
LICENSE_KEY_GITLEAKS:
8+
description: "Gitleaks license key"
9+
required: true
10+
permissions:
11+
contents: read
12+
pull-requests: read
13+
14+
jobs:
15+
git-leaks:
16+
name: Gitleaks
17+
runs-on: ubuntu-latest
18+
timeout-minutes: 5
19+
permissions:
20+
contents: read
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v6
24+
with:
25+
fetch-depth: 0
26+
clean: true
27+
28+
- uses: actions/create-github-app-token@v2
29+
id: app-token
30+
with:
31+
app-id: ${{ vars.GH_ORG_GITLEAKS_APP_ID }}
32+
private-key: ${{ secrets.GH_ORG_GITLEAKS_PRIVATE_KEY }}
33+
34+
- name: Run Gitleaks Scan
35+
uses: gitleaks/gitleaks-action@v2
36+
env:
37+
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
38+
GITLEAKS_LICENSE: ${{ secrets.LICENSE_KEY_GITLEAKS }}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
on:
2+
workflow_call:
3+
secrets:
4+
GH_ORG_PRIVATE_KEY:
5+
description: "GitHub App private key used to create the merge token"
6+
required: true
7+
8+
jobs:
9+
merge-main-develop:
10+
name: Merge main into develop
11+
runs-on: ubuntu-latest
12+
timeout-minutes: 5
13+
steps:
14+
- uses: actions/create-github-app-token@v2
15+
id: app-token
16+
with:
17+
app-id: ${{ vars.GH_ORG_APP_ID }}
18+
private-key: ${{ secrets.GH_ORG_PRIVATE_KEY }}
19+
20+
- name: Set up Git user for GitHub App
21+
run: |
22+
git config --global user.name "semantic-release[bot]"
23+
git config --global user.email "semantic-release[bot]@users.noreply.github.com"
24+
25+
- name: Sync main to develop
26+
env:
27+
# todo remove Fallback to GITHUB_TOKEN if app token is available
28+
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
29+
run: |
30+
set -e
31+
32+
echo "🔄 Cloning repository..."
33+
git clone https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }} repo
34+
cd repo
35+
36+
echo "📦 Setting up remotes..."
37+
git remote add app-origin https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}
38+
git fetch app-origin
39+
40+
echo "🔀 Checking out 'develop' branch..."
41+
git checkout develop
42+
43+
echo "🔁 Attempting fast-forward merge from 'main' to 'develop'..."
44+
git merge --ff-only app-origin/main || echo "⚠️ Fast-forward not possible, continuing..."
45+
46+
echo "📊 Checking for changes after merge..."
47+
if git diff --quiet app-origin/develop; then
48+
echo "✅ No changes to push. Skipping push."
49+
exit 0
50+
fi
51+
52+
echo "🚀 Pushing changes to 'develop'..."
53+
git push app-origin develop
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: "default workflow"
2+
3+
permissions:
4+
contents: write
5+
pull-requests: write
6+
id-token: write
7+
issues: write
8+
9+
on:
10+
pull_request:
11+
branches: [main, develop]
12+
push:
13+
branches: [main, develop]
14+
merge_group:
15+
branches: [main, develop]
16+
17+
jobs:
18+
frontend-workflow:
19+
name: '.'
20+
uses: ./.github/workflows/frontend_workflow.yml
21+
secrets:
22+
GH_ORG_PRIVATE_KEY: ${{ secrets.GH_ORG_PRIVATE_KEY }}
23+
GH_ORG_GITLEAKS_PRIVATE_KEY: ${{ secrets.GH_ORG_GITLEAKS_PRIVATE_KEY }}
24+
LICENSE_KEY_GITLEAKS: ${{ secrets.LICENSE_KEY_GITLEAKS }}
25+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
26+
AWS_OIDC_ROLE_ARN: ${{ secrets.AWS_OIDC_ROLE_ARN }}
27+
AWS_DEPLOYMENT_ROLE_ARN: ${{ secrets.AWS_DEPLOYMENT_ROLE_ARN }}
28+
with:
29+
app-id: ${{ vars.GH_ORG_APP_ID }}

0 commit comments

Comments
 (0)