Melika Kheirieh commited on
Commit
fb51384
Β·
1 Parent(s): 428fd71

ci: harden workflows with safe proxy secret test and improved docker metadata

Browse files
.github/workflows/ci.yml CHANGED
@@ -6,70 +6,70 @@ on:
6
  pull_request:
7
 
8
  concurrency:
9
- group: ci-${{ github.ref }}
10
  cancel-in-progress: true
11
 
12
  jobs:
13
  build-test:
 
14
  runs-on: ubuntu-latest
15
  permissions:
16
  contents: read
17
  env:
18
- # App env (if your tests need them)
19
  PROXY_API_KEY: ${{ secrets.PROXY_API_KEY }}
20
  PROXY_BASE_URL: ${{ secrets.PROXY_BASE_URL }}
21
- # Ensure imports work when running `pytest` via Makefile
22
  PYTHONPATH: ${{ github.workspace }}
23
 
24
  steps:
25
- - name: Checkout
26
  uses: actions/checkout@v4
27
 
28
- - name: Set up Python
29
  uses: actions/setup-python@v5
30
  with:
31
  python-version: "3.12"
32
  cache: pip
33
- cache-dependency-path: |
34
- requirements.txt
35
 
36
- - name: Install dependencies
37
  run: |
38
- python -m pip install -U pip wheel
39
- pip install -r requirements.txt
40
- pip install ruff mypy pytest pytest-cov
41
 
42
- # Optional caches for tool state (speed up CI on subsequent runs)
43
- - name: Cache Ruff
44
  uses: actions/cache@v4
45
  with:
46
  path: .ruff_cache
47
- key: ruff-${{ runner.os }}-${{ hashFiles('**/*.py', 'pyproject.toml', 'ruff.toml', '.pre-commit-config.yaml') }}
48
 
49
- - name: Cache Mypy
50
  uses: actions/cache@v4
51
  with:
52
  path: .mypy_cache
53
- key: mypy-${{ runner.os }}-${{ hashFiles('**/*.py', 'mypy.ini', 'pyproject.toml') }}
54
 
55
- - name: Cache Pytest
56
  uses: actions/cache@v4
57
  with:
58
  path: .pytest_cache
59
- key: pytest-${{ runner.os }}-${{ hashFiles('**/*.py', 'pyproject.toml') }}
60
 
61
- - name: Quality gate (format check, lint, typecheck, tests)
 
62
  run: make check
63
 
64
- - name: Upload coverage (optional)
65
  if: always()
66
  uses: actions/upload-artifact@v4
67
  with:
68
- name: coverage-report
69
- path: ./.coverage
70
  if-no-files-found: ignore
71
 
72
  docker-build:
 
73
  needs: build-test
74
  runs-on: ubuntu-latest
75
  if: ${{ github.ref == 'refs/heads/main' }}
@@ -84,32 +84,39 @@ jobs:
84
  steps:
85
  - uses: actions/checkout@v4
86
 
87
- - name: Set up QEMU
88
  uses: docker/setup-qemu-action@v3
89
 
90
- - name: Set up Docker Buildx
91
  uses: docker/setup-buildx-action@v3
92
 
93
- - name: Login to GHCR
94
  uses: docker/login-action@v3
95
  with:
96
  registry: ${{ env.REGISTRY }}
97
  username: ${{ github.actor }}
98
  password: ${{ secrets.GITHUB_TOKEN }}
99
 
100
- - name: Compute image refs
101
- run: |
102
- OWNER_LC=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
103
- echo "OWNER_LC=$OWNER_LC" >> $GITHUB_ENV
104
- echo "IMAGE=${{ env.REGISTRY }}/${OWNER_LC}/${{ env.IMAGE_NAME }}:${{ github.sha }}" >> $GITHUB_ENV
105
- echo "LATEST=${{ env.REGISTRY }}/${OWNER_LC}/${{ env.IMAGE_NAME }}:latest" >> $GITHUB_ENV
106
-
107
- - name: Build and push (with cache)
 
 
 
 
 
 
 
108
  uses: docker/build-push-action@v6
109
  with:
110
  push: true
111
- tags: |
112
- ${{ env.IMAGE }}
113
- ${{ env.LATEST }}
114
  cache-from: type=gha
115
  cache-to: type=gha,mode=max
 
 
6
  pull_request:
7
 
8
  concurrency:
9
+ group: ${{ github.workflow }}-${{ github.ref }}
10
  cancel-in-progress: true
11
 
12
  jobs:
13
  build-test:
14
+ name: πŸ§ͺ Build & Test
15
  runs-on: ubuntu-latest
16
  permissions:
17
  contents: read
18
  env:
 
19
  PROXY_API_KEY: ${{ secrets.PROXY_API_KEY }}
20
  PROXY_BASE_URL: ${{ secrets.PROXY_BASE_URL }}
 
21
  PYTHONPATH: ${{ github.workspace }}
22
 
23
  steps:
24
+ - name: 🧾 Checkout
25
  uses: actions/checkout@v4
26
 
27
+ - name: 🐍 Set up Python
28
  uses: actions/setup-python@v5
29
  with:
30
  python-version: "3.12"
31
  cache: pip
32
+ cache-dependency-path: requirements.txt
 
33
 
34
+ - name: πŸ“¦ Install dependencies
35
  run: |
36
+ python -m pip install -U pip wheel
37
+ pip install -r requirements.txt
38
+ pip install ruff mypy pytest pytest-cov
39
 
40
+ # ---------- Cache tool states ----------
41
+ - name: βš™οΈ Cache Ruff
42
  uses: actions/cache@v4
43
  with:
44
  path: .ruff_cache
45
+ key: ruff-${{ runner.os }}-${{ hashFiles('pyproject.toml', 'ruff.toml', '.pre-commit-config.yaml', '**/*.py') }}
46
 
47
+ - name: βš™οΈ Cache Mypy
48
  uses: actions/cache@v4
49
  with:
50
  path: .mypy_cache
51
+ key: mypy-${{ runner.os }}-${{ hashFiles('mypy.ini', 'pyproject.toml', '**/*.py') }}
52
 
53
+ - name: βš™οΈ Cache Pytest
54
  uses: actions/cache@v4
55
  with:
56
  path: .pytest_cache
57
+ key: pytest-${{ runner.os }}-${{ hashFiles('pyproject.toml', '**/*.py') }}
58
 
59
+ # ---------- Quality Gate ----------
60
+ - name: 🧹 Quality gate (format, lint, typecheck, tests)
61
  run: make check
62
 
63
+ - name: πŸ“Š Upload coverage report
64
  if: always()
65
  uses: actions/upload-artifact@v4
66
  with:
67
+ name: coverage-xml
68
+ path: coverage.xml
69
  if-no-files-found: ignore
70
 
71
  docker-build:
72
+ name: 🐳 Build & Push Docker
73
  needs: build-test
74
  runs-on: ubuntu-latest
75
  if: ${{ github.ref == 'refs/heads/main' }}
 
84
  steps:
85
  - uses: actions/checkout@v4
86
 
87
+ - name: βš™οΈ Set up QEMU
88
  uses: docker/setup-qemu-action@v3
89
 
90
+ - name: βš™οΈ Set up Docker Buildx
91
  uses: docker/setup-buildx-action@v3
92
 
93
+ - name: πŸ” Login to GHCR
94
  uses: docker/login-action@v3
95
  with:
96
  registry: ${{ env.REGISTRY }}
97
  username: ${{ github.actor }}
98
  password: ${{ secrets.GITHUB_TOKEN }}
99
 
100
+ - name: 🧾 Docker metadata
101
+ id: meta
102
+ uses: docker/metadata-action@v5
103
+ with:
104
+ images: |
105
+ ${{ env.REGISTRY }}/${{ github.repository_owner }}/nl2sql-copilot
106
+ tags: |
107
+ type=raw,value=latest
108
+ type=sha
109
+ labels: |
110
+ org.opencontainers.image.source=${{ github.repository }}
111
+ org.opencontainers.image.revision=${{ github.sha }}
112
+ org.opencontainers.image.created=${{ github.run_id }}
113
+
114
+ - name: πŸ—οΈ Build and push image
115
  uses: docker/build-push-action@v6
116
  with:
117
  push: true
118
+ tags: ${{ steps.meta.outputs.tags }}
119
+ labels: ${{ steps.meta.outputs.labels }}
 
120
  cache-from: type=gha
121
  cache-to: type=gha,mode=max
122
+ platforms: linux/amd64
.github/workflows/test-proxy-secrets.yml CHANGED
@@ -9,6 +9,7 @@ jobs:
9
  env:
10
  PROXY_API_KEY: ${{ secrets.PROXY_API_KEY }}
11
  PROXY_BASE_URL: ${{ secrets.PROXY_BASE_URL }}
 
12
  steps:
13
  - name: 🧾 Check runner environment
14
  run: |
@@ -29,11 +30,8 @@ jobs:
29
  fi
30
  echo "βœ… Both secrets are present."
31
 
32
- - name: πŸ§ͺ Safe test with masking
33
  run: |
34
- echo "PROXY_API_KEY (masked) = ${PROXY_API_KEY}"
35
- echo "Length of PROXY_API_KEY = ${#PROXY_API_KEY}"
36
- echo "PROXY_BASE_URL = ${PROXY_BASE_URL}"
37
  python3 - << 'PY'
38
  import os
39
  key = os.getenv("PROXY_API_KEY")
 
9
  env:
10
  PROXY_API_KEY: ${{ secrets.PROXY_API_KEY }}
11
  PROXY_BASE_URL: ${{ secrets.PROXY_BASE_URL }}
12
+
13
  steps:
14
  - name: 🧾 Check runner environment
15
  run: |
 
30
  fi
31
  echo "βœ… Both secrets are present."
32
 
33
+ - name: πŸ§ͺ Validate secrets accessibility (Python)
34
  run: |
 
 
 
35
  python3 - << 'PY'
36
  import os
37
  key = os.getenv("PROXY_API_KEY")