Skip to content

Commit a01ac44

Browse files
JeromeBuclaude
andcommitted
ci: add SILL deployment workflows and sync-upstream
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 33bad8f commit a01ac44

4 files changed

Lines changed: 171 additions & 170 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 67 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ jobs:
2121
curl -o iocs.csv https://raw.githubusercontent.com/DataDog/indicators-of-compromise/refs/heads/main/shai-hulud-2.0/consolidated_iocs.csv
2222
- name: Scan dependencies against IOCs
2323
run: node scripts/scan-dependencies.js
24-
2524
validations:
26-
runs-on: ubuntu-latest
2725
needs: security-scan
26+
runs-on: ubuntu-latest
2827
env:
2928
DATABASE_URL: postgresql://catalogi:pg_password@localhost:5432/db
3029
services:
@@ -72,169 +71,76 @@ jobs:
7271
runs-on: ubuntu-latest
7372
needs: [validations, e2e]
7473
outputs:
75-
from_version: ${{ steps.step1.outputs.from_version }}
76-
to_version: ${{ steps.step1.outputs.to_version }}
77-
is_upgraded_version: ${{ steps.step1.outputs.is_upgraded_version }}
74+
is_upgraded_in_preprod: ${{ steps.check_version.outputs.is_upgraded_in_preprod }}
75+
is_upgraded_version: ${{ steps.check_version.outputs.is_upgraded_version }}
76+
to_version: ${{ steps.check_version.outputs.to_version }}
77+
from_version: ${{ steps.check_version.outputs.from_version }}
7878
steps:
79-
- uses: garronej/ts-ci@v2.1.5
80-
id: step1
81-
with:
82-
action_name: is_package_json_version_upgraded
83-
- run: |
84-
echo "from_version=${{ steps.step1.outputs.from_version }}"
85-
echo "to_version=${{ steps.step1.outputs.to_version }}"
86-
echo "is_upgraded_version=${{ steps.step1.outputs.is_upgraded_version }}"
87-
88-
create_tag:
89-
name: Create version tag
90-
runs-on: ubuntu-latest
91-
needs:
92-
- check_if_version_upgraded
93-
if: needs.check_if_version_upgraded.outputs.is_upgraded_version == 'true'
94-
env:
95-
TO_VERSION: ${{ needs.check_if_version_upgraded.outputs.to_version }}
96-
steps:
97-
- name: Checkout repository
98-
uses: actions/checkout@v6
99-
- name: Create tag
100-
run: |
101-
git config --local user.email "actions@github.com"
102-
git config --local user.name "GitHub Actions"
103-
git tag -a v${{ env.TO_VERSION }} -m "Deployment tag for v${{ env.TO_VERSION }}"
104-
git push --tags
105-
106-
create_github_release:
107-
name: "Create release notes"
108-
runs-on: ubuntu-latest
109-
needs:
110-
- check_if_version_upgraded
111-
- create_tag
112-
if: |
113-
needs.check_if_version_upgraded.outputs.is_upgraded_version == 'true' && github.event_name == 'push'
114-
env:
115-
RELEASE_TAG: v${{ needs.check_if_version_upgraded.outputs.to_version }}
116-
steps:
117-
- name: Checkout repository
118-
uses: actions/checkout@v6
119-
- name: Install Helm
120-
uses: azure/setup-helm@v4
121-
- name: Build Helm chart dependencies
122-
run: |
123-
helm dependency build helm-charts/catalogi
124-
- name: Package Helm chart
125-
run: |
126-
helm package helm-charts/catalogi
127-
- name: "Generate release on github"
128-
uses: softprops/action-gh-release@v2
129-
with:
130-
name: Release ${{ env.RELEASE_TAG }}
131-
prerelease: false
132-
tag_name: ${{ env.RELEASE_TAG }}
133-
generate_release_notes: true
134-
files: catalogi-*.tgz
135-
token: ${{ secrets.GITHUB_TOKEN }}
136-
137-
publish_helm_index:
138-
name: Publish Helm chart index
139-
runs-on: ubuntu-latest
140-
permissions:
141-
contents: write
142-
needs:
143-
- check_if_version_upgraded
144-
- create_github_release
145-
if: needs.check_if_version_upgraded.outputs.is_upgraded_version == 'true'
146-
env:
147-
TO_VERSION: ${{ needs.check_if_version_upgraded.outputs.to_version }}
148-
steps:
149-
- name: Generate GitHub App token
150-
id: generate_token
151-
uses: tibdex/github-app-token@v2
152-
with:
153-
app_id: ${{ secrets.RELEASE_APP_ID }}
154-
private_key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
155-
156-
- name: Checkout repository
157-
uses: actions/checkout@v6
158-
with:
159-
token: ${{ steps.generate_token.outputs.token }}
160-
fetch-depth: 0
161-
162-
- name: Configure git
163-
run: |
164-
git config --local user.email "actions@github.com"
165-
git config --local user.name "GitHub Actions"
166-
167-
- name: Setup gh-pages branch
79+
- uses: actions/checkout@v6
80+
- name: Check version upgrade
81+
id: check_version
16882
run: |
169-
git fetch origin
170-
171-
if git ls-remote --heads origin gh-pages | grep gh-pages; then
172-
git checkout gh-pages
83+
# Get current version from package.json
84+
CURRENT_VERSION=$(jq -r '.version' package.json)
85+
echo "Version in package.json: $CURRENT_VERSION"
86+
87+
# Get deployed version from preprod API
88+
PRE_PROD_DEPLOYED_VERSION=$(curl -s "https://code.gouv.fr/sill-preprod/api/getApiVersion" | jq -r '.result.data.json')
89+
PROD_DEPLOYED_VERSION=$(curl -s "https://code.gouv.fr/sill/api/getApiVersion" | jq -r '.result.data.json')
90+
echo "Deployed version in preprod: $PRE_PROD_DEPLOYED_VERSION"
91+
echo "Deployed version in prod: $PROD_DEPLOYED_VERSION"
92+
93+
# Simple comparison: check if versions are different
94+
if [ "$CURRENT_VERSION" != "$PRE_PROD_DEPLOYED_VERSION" ]; then
95+
IS_UPGRADED_IN_PRE_PROD="true"
96+
IS_UPGRADED="true"
97+
echo "✅ Version different from preprod ($PRE_PROD_DEPLOYED_VERSION), should deploy: $CURRENT_VERSION"
98+
elif [ "$CURRENT_VERSION" != "$PROD_DEPLOYED_VERSION" ]; then
99+
IS_UPGRADED="true"
100+
echo "✅ Version different from prod ($PROD_DEPLOYED_VERSION), should deploy: $CURRENT_VERSION"
173101
else
174-
git checkout -b gh-pages
102+
IS_UPGRADED="false"
103+
echo "ℹ️ Version unchanged: $CURRENT_VERSION"
175104
fi
176-
177-
git reset --hard origin/main
178-
179-
- name: Install Helm
180-
uses: azure/setup-helm@v4
181-
182-
- name: Create charts directory
183-
run: mkdir -p docs/charts
184-
185-
- name: Download chart from release
186-
run: |
187-
gh release download v${TO_VERSION} --pattern "catalogi-*.tgz" --dir docs/charts/
188-
env:
189-
GH_TOKEN: ${{ github.token }}
190-
191-
- name: Generate Helm repository index with merge
192-
run: |
193-
helm repo index docs/charts/ --url https://github.com/codegouvfr/catalogi/releases/download/v${TO_VERSION}/ --merge docs/charts/index.yaml
194-
195-
- name: Commit and push to gh-pages
196-
run: |
197-
git add docs/charts/index.yaml
198-
git commit -m "chore: update Helm chart index for v${TO_VERSION}"
199-
git push origin gh-pages --force
200-
201-
docker:
202-
name: Build and push Docker images
203-
runs-on: ubuntu-latest
105+
106+
echo "Is version upgraded: $IS_UPGRADED"
107+
108+
# Set outputs
109+
echo "is_upgraded_version=$IS_UPGRADED" >> $GITHUB_OUTPUT
110+
echo "is_upgraded_in_preprod=$IS_UPGRADED_IN_PRE_PROD" >> $GITHUB_OUTPUT
111+
echo "to_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
112+
echo "from_version=$PRE_PROD_DEPLOYED_VERSION" >> $GITHUB_OUTPUT
113+
114+
trigger_pre_production_deploy:
204115
needs:
205116
- check_if_version_upgraded
206-
if: needs.check_if_version_upgraded.outputs.is_upgraded_version == 'true'
207-
steps:
208-
- uses: actions/checkout@v6
209-
- uses: docker/setup-qemu-action@v3
210-
- uses: docker/setup-buildx-action@v3
211-
- uses: docker/login-action@v3
212-
with:
213-
username: ${{ secrets.DOCKERHUB_USERNAME }}
214-
password: ${{ secrets.DOCKERHUB_TOKEN }}
215-
- name: Computing Docker image tags
216-
id: step1
217-
env:
218-
TO_VERSION: ${{ needs.check_if_version_upgraded.outputs.to_version }}
219-
run: |
220-
OUT_API=$GITHUB_REPOSITORY-api:$TO_VERSION,$GITHUB_REPOSITORY-api:latest
221-
OUT_API=$(echo "$OUT_API" | awk '{print tolower($0)}')
222-
echo ::set-output name=docker_api_tags::$OUT_API
223-
224-
OUT_WEB=$GITHUB_REPOSITORY-web:$TO_VERSION,$GITHUB_REPOSITORY-web:latest
225-
OUT_WEB=$(echo "$OUT_WEB" | awk '{print tolower($0)}')
226-
echo ::set-output name=docker_web_tags::$OUT_WEB
227-
228-
- uses: docker/build-push-action@v5
229-
with:
230-
push: true
231-
context: .
232-
file: ./Dockerfile.api
233-
tags: ${{ steps.step1.outputs.docker_api_tags }}
234-
- uses: docker/build-push-action@v5
235-
with:
236-
push: true
237-
context: .
238-
file: ./Dockerfile.web
239-
tags: ${{ steps.step1.outputs.docker_web_tags }}
117+
if: needs.check_if_version_upgraded.outputs.is_upgraded_in_preprod == 'true'
118+
uses: ./.github/workflows/trigger-deploy.yaml
119+
with:
120+
server_host: code.gouv.fr
121+
server_user: web
122+
deploy_script_path: ./update-sill-preprod.sh
123+
server_ssh_key_path: ~/.ssh/sill-data
124+
environment_name: pre-production
125+
version: v${{ needs.check_if_version_upgraded.outputs.to_version }}
126+
secrets:
127+
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
128+
129+
130+
trigger_production_deploy:
131+
needs:
132+
- trigger_pre_production_deploy
133+
- check_if_version_upgraded
134+
if: needs.check_if_version_upgraded.outputs.is_upgraded_version == 'true' && (needs.trigger_pre_production_deploy.result == 'success' || needs.trigger_pre_production_deploy.result == 'skipped')
135+
uses: ./.github/workflows/trigger-deploy.yaml
136+
with:
137+
server_host: code.gouv.fr
138+
server_user: web
139+
deploy_script_path: ./update-sill-docker-compose.sh
140+
server_ssh_key_path: ~/.ssh/sill-data
141+
environment_name: production
142+
version: v${{ needs.check_if_version_upgraded.outputs.to_version }}
143+
github_environment: production
144+
secrets:
145+
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
240146

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Sync upstream
2+
3+
on:
4+
schedule:
5+
- cron: '0 7 * * *' # every day at 7 AM UTC
6+
workflow_dispatch:
7+
8+
jobs:
9+
sync:
10+
name: Sync repository with upstream repository
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout fork
14+
uses: actions/checkout@v4
15+
with:
16+
token: ${{ secrets.PAT_FOR_UPSTREAM_SYNC }}
17+
fetch-depth: 0
18+
19+
- name: Configure Git
20+
run: |
21+
git config user.name "github-actions[bot]"
22+
git config user.email "github-actions[bot]@users.noreply.github.com"
23+
24+
- name: Add upstream remote
25+
run: |
26+
git remote add upstream https://github.com/codegouvfr/catalogi.git
27+
git fetch upstream
28+
29+
- name: Sync with upstream/main
30+
run: |
31+
git checkout main
32+
git rebase upstream/main
33+
34+
- name: Push to origin
35+
run: git push origin main --force-with-lease --no-verify
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: Deploy to Server
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
server_host:
7+
description: 'Server hostname or IP address'
8+
required: true
9+
type: string
10+
server_user:
11+
description: 'SSH user'
12+
required: true
13+
type: string
14+
deploy_script_path:
15+
description: 'Deployment script path on remote server (e.g., ./update-sill-preprod.sh)'
16+
required: true
17+
type: string
18+
server_ssh_key_path:
19+
description: 'Path to SSH key on remote server for GitHub access (e.g., ~/.ssh/sill-data)'
20+
required: false
21+
type: string
22+
default: '~/.ssh/sill-data'
23+
environment_name:
24+
description: 'Environment name for display purposes'
25+
required: true
26+
type: string
27+
version:
28+
description: 'Version to deploy (with v prefix)'
29+
required: true
30+
type: string
31+
github_environment:
32+
description: 'GitHub environment for approvals (optional)'
33+
required: false
34+
type: string
35+
secrets:
36+
SSH_PRIVATE_KEY:
37+
required: true
38+
39+
jobs:
40+
deploy:
41+
name: "Deploy to ${{ inputs.environment_name }}"
42+
runs-on: ubuntu-latest
43+
environment: ${{ inputs.github_environment }}
44+
concurrency:
45+
group: deploy-to-${{ inputs.environment_name }}
46+
cancel-in-progress: true
47+
steps:
48+
- run: echo "${{ inputs.version }} - Triggering ${{ inputs.environment_name }} deploy"
49+
- name: Set up SSH, trigger deployment script
50+
timeout-minutes: 10
51+
run: |
52+
set -e
53+
set -o pipefail
54+
mkdir -p ~/.ssh
55+
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
56+
chmod 600 ~/.ssh/id_ed25519
57+
ssh-keyscan ${{ inputs.server_host }} >> ~/.ssh/known_hosts
58+
59+
echo "Connecting to ${{ inputs.server_host }} and running deployment script..."
60+
ssh ${{ inputs.server_user }}@${{ inputs.server_host }} "bash -c 'set -e && eval \"\$(ssh-agent -s)\" && ssh-add ${{ inputs.server_ssh_key_path }} && ${{ inputs.deploy_script_path }} ${{ inputs.version }}'" 2>&1 | tee deploy.log
61+
62+
echo "✅ ${{ inputs.environment_name }} deployment completed successfully"
63+
env:
64+
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}

README.md

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Documentation is available [here](https://codegouvfr.github.io/catalogi/)
1919

2020
## Code organization
2121

22-
This monorepo is made of several directories:
22+
Mais quels logiciels libres utiliser et pourquoi ? Quand plusieurs logiciels libres remplissent la même fonction, lequel privilégier ? Quelle version minimale est acceptable ?
2323

2424
- api: Application API (also includes jobs, that can be run periodically)
2525
- web: Web frontend
@@ -28,18 +28,14 @@ This monorepo is made of several directories:
2828

2929
## Governance and contributions
3030

31-
[![img](https://img.shields.io/badge/code.gouv.fr-contributif-blue.svg)](https://code.gouv.fr/documentation/#quels-degres-douverture-pour-les-codes-sources)
31+
# Historique
3232

33-
See [GOVERNANCE](GOVERNANCE.md) and [CONTRIBUTING](CONTRIBUTING.md).
34-
35-
## Discuss with us
36-
37-
You are welcome to join the [Catalogi Matrix channel](https://matrix.to/#/#catalogi:matrix.org).
33+
Le SILL était à l'origine une liste sous format PDF qui était mise à jour tous les ans par les groupes MIM (Mutualisation InterMinistérielle).
3834

3935
## License
4036

41-
2021-2025 Direction interministérielle du numérique, mission logiciels libres.
37+
Cette liste servaient aux DSI des ministères à faire les mises à jour nécessaires et à découvrir des logiciels libres utilisés par d'autres ministères.
4238

43-
The code in this repository is published under [licence MIT](LICENSES/MIT.txt).
39+
En 2019, le SILL a été publié sous forme d'une application web à l'adresse https://sill.etalab.gouv.fr, qui redirigeait vers https://sill.code.gouv.fr depuis février 2023 jusqu'à présent, et désormais sur https://code.gouv.fr/sill. La page de visualisation était générée à partir de fichiers `csv` maintenus manuellement sur un dépôt public.
4440

4541
The documentation is published under [licence Ouverte 2.0](LICENSES/Etalab-2.0.md) and [CC-BY-4.0](LICENSES/CC-BY-4.0.txt).

0 commit comments

Comments
 (0)