Setup updates_url for releasesUnverified
c04784f parent: 220cb01 modified
.gitlab-ci.yml +150 -11 | @@ -1,16 +1,155 @@ | ||
| 1 | -# You can override the included template(s) by including variable overrides | |
| 2 | -# SAST customization: https://docs.gitlab.com/user/application_security/sast/#available-cicd-variables | |
| 3 | -# Secret Detection customization: https://docs.gitlab.com/user/application_security/secret_detection/pipeline/configure/ | |
| 4 | -# Dependency Scanning customization: https://docs.gitlab.com/user/application_security/dependency_scanning/dependency_scanning_sbom/#customizing-analyzer-behavior | |
| 5 | -# Container Scanning customization: https://docs.gitlab.com/user/application_security/container_scanning/#customizing-analyzer-behavior | |
| 6 | -# Note that environment variables can be set in several places | |
| 7 | -# See https://docs.gitlab.com/ci/variables/#cicd-variable-precedence | |
| 1 | +# Pipeline CI/CD re:group | |
| 2 | +# - lint : web-ext lint sur chaque push / MR | |
| 3 | +# - secret-detection : scan de secrets (template GitLab) | |
| 4 | +# - sign : signe le .xpi via l'API AMO (unlisted) sur tag vX.Y.Z | |
| 5 | +# - publish : pousse le .xpi signé dans le Package Registry (stockage durable) | |
| 6 | +# - pages : reconstruit updates.json + miroir des .xpi sur GitLab Pages | |
| 7 | +# | |
| 8 | +# Variables CI à définir (Settings > CI/CD > Variables), masked + protected : | |
| 9 | +# WEB_EXT_API_KEY (jwtIssuer depuis AMO > Manage API Keys) | |
| 10 | +# WEB_EXT_API_SECRET (jwtSecret) | |
| 11 | +# web-ext lit ces deux variables automatiquement : jamais passées en argument. | |
| 12 | +# | |
| 13 | +# Le job de release ne tourne que sur tags PROTÉGÉS (motif v* à protéger | |
| 14 | +# dans Settings > Repository > Protected tags) → seuls les tags protégés | |
| 15 | +# voient les variables protégées. | |
| 16 | + | |
| 8 | 17 | stages: |
| 9 | -- test | |
| 10 | -- secret-detection | |
| 18 | + - test | |
| 19 | + - secret-detection | |
| 20 | + - sign | |
| 21 | + - publish | |
| 22 | + - pages | |
| 23 | + | |
| 11 | 24 | variables: |
| 12 | 25 | SECRET_DETECTION_ENABLED: 'true' |
| 26 | + # Base publique servie par GitLab Pages (unique domain désactivé). | |
| 27 | + PAGES_BASE: 'https://juuduu.gitlab.io/re-group-firefox-addon' | |
| 28 | + # Nom du paquet générique dans le registry. | |
| 29 | + PKG_NAME: 're-group' | |
| 30 | + | |
| 31 | +include: | |
| 32 | + - template: Security/Secret-Detection.gitlab-ci.yml | |
| 33 | + | |
| 13 | 34 | secret_detection: |
| 14 | 35 | stage: secret-detection |
| 15 | -include: | |
| 16 | -- template: Security/Secret-Detection.gitlab-ci.yml | |
| 36 | + | |
| 37 | +# --------------------------------------------------------------------------- | |
| 38 | +# Lint — rapide, sur branches et MR (attrape ce qu'AMO refuserait). | |
| 39 | +# --------------------------------------------------------------------------- | |
| 40 | +lint: | |
| 41 | + stage: test | |
| 42 | + image: node:20 | |
| 43 | + rules: | |
| 44 | + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' | |
| 45 | + - if: '$CI_COMMIT_TAG == null && $CI_PIPELINE_SOURCE == "push"' | |
| 46 | + script: | |
| 47 | + - npm install --no-save web-ext@^10 | |
| 48 | + - npx web-ext lint --source-dir=. | |
| 49 | + | |
| 50 | +# --------------------------------------------------------------------------- | |
| 51 | +# Sign — sur tag vX.Y.Z uniquement. Vérifie que le manifest == le tag, | |
| 52 | +# puis signe via AMO (canal unlisted, signature automatique). | |
| 53 | +# --------------------------------------------------------------------------- | |
| 54 | +sign: | |
| 55 | + stage: sign | |
| 56 | + image: node:20 | |
| 57 | + rules: | |
| 58 | + - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/' | |
| 59 | + script: | |
| 60 | + - VERSION="${CI_COMMIT_TAG#v}" | |
| 61 | + - MANIFEST_VERSION="$(node -p "require('./manifest.json').version")" | |
| 62 | + - | | |
| 63 | + if [ "$VERSION" != "$MANIFEST_VERSION" ]; then | |
| 64 | + echo "Le tag ($VERSION) ne correspond pas à manifest.json ($MANIFEST_VERSION)." | |
| 65 | + exit 1 | |
| 66 | + fi | |
| 67 | + - npm install --no-save web-ext@^10 | |
| 68 | + # WEB_EXT_API_KEY / WEB_EXT_API_SECRET lus depuis l'environnement. | |
| 69 | + - npx web-ext sign --channel=unlisted --source-dir=. --artifacts-dir=signed | |
| 70 | + - mkdir -p out | |
| 71 | + - cp "$(ls -t signed/*.xpi | head -n1)" "out/${PKG_NAME}-${VERSION}.xpi" | |
| 72 | + - echo "VERSION=${VERSION}" >> build.env | |
| 73 | + artifacts: | |
| 74 | + paths: | |
| 75 | + - out/ | |
| 76 | + reports: | |
| 77 | + dotenv: build.env | |
| 78 | + | |
| 79 | +# --------------------------------------------------------------------------- | |
| 80 | +# Publish — dépose le .xpi signé dans le Package Registry générique. | |
| 81 | +# Stockage durable et versionné, jamais écrasé. | |
| 82 | +# --------------------------------------------------------------------------- | |
| 83 | +publish: | |
| 84 | + stage: publish | |
| 85 | + image: curlimages/curl:latest | |
| 86 | + needs: [sign] | |
| 87 | + rules: | |
| 88 | + - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/' | |
| 89 | + script: | |
| 90 | + - FILE="${PKG_NAME}-${VERSION}.xpi" | |
| 91 | + - | | |
| 92 | + curl --fail --silent --show-error \ | |
| 93 | + --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \ | |
| 94 | + --upload-file "out/${FILE}" \ | |
| 95 | + "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PKG_NAME}/${VERSION}/${FILE}" | |
| 96 | + | |
| 97 | +# --------------------------------------------------------------------------- | |
| 98 | +# Release — crée une Release GitLab avec un lien vers le .xpi (pour les humains). | |
| 99 | +# --------------------------------------------------------------------------- | |
| 100 | +release: | |
| 101 | + stage: publish | |
| 102 | + image: registry.gitlab.com/gitlab-org/release-cli:latest | |
| 103 | + needs: [sign, publish] | |
| 104 | + rules: | |
| 105 | + - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/' | |
| 106 | + script: | |
| 107 | + - echo "Release ${CI_COMMIT_TAG}" | |
| 108 | + release: | |
| 109 | + tag_name: '$CI_COMMIT_TAG' | |
| 110 | + name: 're:group $CI_COMMIT_TAG' | |
| 111 | + description: 'Version signée disponible sur la page de mise à jour.' | |
| 112 | + assets: | |
| 113 | + links: | |
| 114 | + - name: 're_group ${VERSION} (.xpi signé)' | |
| 115 | + url: '${PAGES_BASE}/${PKG_NAME}-${VERSION}.xpi' | |
| 116 | + | |
| 117 | +# --------------------------------------------------------------------------- | |
| 118 | +# Pages — reconstruit le site public : miroir de TOUS les .xpi du registry | |
| 119 | +# + updates.json regénéré depuis la liste complète des versions. | |
| 120 | +# Aucun état à committer : la source de vérité est le registry. | |
| 121 | +# --------------------------------------------------------------------------- | |
| 122 | +pages: | |
| 123 | + stage: pages | |
| 124 | + image: alpine:latest | |
| 125 | + needs: [publish] | |
| 126 | + rules: | |
| 127 | + - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/' | |
| 128 | + script: | |
| 129 | + - apk add --no-cache curl jq | |
| 130 | + - mkdir -p public | |
| 131 | + - ADDON_ID="$(jq -r '.browser_specific_settings.gecko.id' manifest.json)" | |
| 132 | + # Liste toutes les versions du paquet générique PKG_NAME. | |
| 133 | + - | | |
| 134 | + curl --fail --silent --show-error --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \ | |
| 135 | + "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages?package_type=generic&per_page=100" \ | |
| 136 | + > packages.json | |
| 137 | + - VERSIONS="$(jq -r --arg n "$PKG_NAME" '.[] | select(.name==$n) | .version' packages.json | sort -V)" | |
| 138 | + - echo "[]" > entries.json | |
| 139 | + - | | |
| 140 | + for V in $VERSIONS; do | |
| 141 | + FILE="${PKG_NAME}-${V}.xpi" | |
| 142 | + curl --fail --silent --show-error --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \ | |
| 143 | + -o "public/${FILE}" \ | |
| 144 | + "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PKG_NAME}/${V}/${FILE}" | |
| 145 | + jq --arg v "$V" --arg link "${PAGES_BASE}/${FILE}" \ | |
| 146 | + '. += [{"version":$v,"update_link":$link}]' entries.json > entries.tmp | |
| 147 | + mv entries.tmp entries.json | |
| 148 | + done | |
| 149 | + - | | |
| 150 | + jq -n --arg id "$ADDON_ID" --slurpfile e entries.json \ | |
| 151 | + '{addons: {($id): {updates: $e[0]}}}' > public/updates.json | |
| 152 | + - cat public/updates.json | |
| 153 | + artifacts: | |
| 154 | + paths: | |
| 155 | + - public | |
| @@ -1,16 +1,155 @@ | |||
| 1 | -# You can override the included template(s) by including variable overrides | 1 | +# Pipeline CI/CD re:group |
| 2 | -# SAST customization: https://docs.gitlab.com/user/application_security/sast/#available-cicd-variables | 2 | +# - lint : web-ext lint sur chaque push / MR |
| 3 | -# Secret Detection customization: https://docs.gitlab.com/user/application_security/secret_detection/pipeline/configure/ | 3 | +# - secret-detection : scan de secrets (template GitLab) |
| 4 | -# Dependency Scanning customization: https://docs.gitlab.com/user/application_security/dependency_scanning/dependency_scanning_sbom/#customizing-analyzer-behavior | 4 | +# - sign : signe le .xpi via l'API AMO (unlisted) sur tag vX.Y.Z |
| 5 | -# Container Scanning customization: https://docs.gitlab.com/user/application_security/container_scanning/#customizing-analyzer-behavior | 5 | +# - publish : pousse le .xpi signé dans le Package Registry (stockage durable) |
| 6 | -# Note that environment variables can be set in several places | 6 | +# - pages : reconstruit updates.json + miroir des .xpi sur GitLab Pages |
| 7 | -# See https://docs.gitlab.com/ci/variables/#cicd-variable-precedence | 7 | +# |
| 8 | +# Variables CI à définir (Settings > CI/CD > Variables), masked + protected : | ||
| 9 | +# WEB_EXT_API_KEY (jwtIssuer depuis AMO > Manage API Keys) | ||
| 10 | +# WEB_EXT_API_SECRET (jwtSecret) | ||
| 11 | +# web-ext lit ces deux variables automatiquement : jamais passées en argument. | ||
| 12 | +# | ||
| 13 | +# Le job de release ne tourne que sur tags PROTÉGÉS (motif v* à protéger | ||
| 14 | +# dans Settings > Repository > Protected tags) → seuls les tags protégés | ||
| 15 | +# voient les variables protégées. | ||
| 16 | + | ||
| 8 | stages: | 17 | stages: |
| 9 | -- test | 18 | + - test |
| 10 | -- secret-detection | 19 | + - secret-detection |
| 20 | + - sign | ||
| 21 | + - publish | ||
| 22 | + - pages | ||
| 23 | + | ||
| 11 | variables: | 24 | variables: |
| 12 | SECRET_DETECTION_ENABLED: 'true' | 25 | SECRET_DETECTION_ENABLED: 'true' |
| 26 | + # Base publique servie par GitLab Pages (unique domain désactivé). | ||
| 27 | + PAGES_BASE: 'https://juuduu.gitlab.io/re-group-firefox-addon' | ||
| 28 | + # Nom du paquet générique dans le registry. | ||
| 29 | + PKG_NAME: 're-group' | ||
| 30 | + | ||
| 31 | +include: | ||
| 32 | + - template: Security/Secret-Detection.gitlab-ci.yml | ||
| 33 | + | ||
| 13 | secret_detection: | 34 | secret_detection: |
| 14 | stage: secret-detection | 35 | stage: secret-detection |
| 15 | -include: | 36 | + |
| 16 | -- template: Security/Secret-Detection.gitlab-ci.yml | 37 | +# --------------------------------------------------------------------------- |
| 38 | +# Lint — rapide, sur branches et MR (attrape ce qu'AMO refuserait). | ||
| 39 | +# --------------------------------------------------------------------------- | ||
| 40 | +lint: | ||
| 41 | + stage: test | ||
| 42 | + image: node:20 | ||
| 43 | + rules: | ||
| 44 | + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' | ||
| 45 | + - if: '$CI_COMMIT_TAG == null && $CI_PIPELINE_SOURCE == "push"' | ||
| 46 | + script: | ||
| 47 | + - npm install --no-save web-ext@^10 | ||
| 48 | + - npx web-ext lint --source-dir=. | ||
| 49 | + | ||
| 50 | +# --------------------------------------------------------------------------- | ||
| 51 | +# Sign — sur tag vX.Y.Z uniquement. Vérifie que le manifest == le tag, | ||
| 52 | +# puis signe via AMO (canal unlisted, signature automatique). | ||
| 53 | +# --------------------------------------------------------------------------- | ||
| 54 | +sign: | ||
| 55 | + stage: sign | ||
| 56 | + image: node:20 | ||
| 57 | + rules: | ||
| 58 | + - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/' | ||
| 59 | + script: | ||
| 60 | + - VERSION="${CI_COMMIT_TAG#v}" | ||
| 61 | + - MANIFEST_VERSION="$(node -p "require('./manifest.json').version")" | ||
| 62 | + - | | ||
| 63 | + if [ "$VERSION" != "$MANIFEST_VERSION" ]; then | ||
| 64 | + echo "Le tag ($VERSION) ne correspond pas à manifest.json ($MANIFEST_VERSION)." | ||
| 65 | + exit 1 | ||
| 66 | + fi | ||
| 67 | + - npm install --no-save web-ext@^10 | ||
| 68 | + # WEB_EXT_API_KEY / WEB_EXT_API_SECRET lus depuis l'environnement. | ||
| 69 | + - npx web-ext sign --channel=unlisted --source-dir=. --artifacts-dir=signed | ||
| 70 | + - mkdir -p out | ||
| 71 | + - cp "$(ls -t signed/*.xpi | head -n1)" "out/${PKG_NAME}-${VERSION}.xpi" | ||
| 72 | + - echo "VERSION=${VERSION}" >> build.env | ||
| 73 | + artifacts: | ||
| 74 | + paths: | ||
| 75 | + - out/ | ||
| 76 | + reports: | ||
| 77 | + dotenv: build.env | ||
| 78 | + | ||
| 79 | +# --------------------------------------------------------------------------- | ||
| 80 | +# Publish — dépose le .xpi signé dans le Package Registry générique. | ||
| 81 | +# Stockage durable et versionné, jamais écrasé. | ||
| 82 | +# --------------------------------------------------------------------------- | ||
| 83 | +publish: | ||
| 84 | + stage: publish | ||
| 85 | + image: curlimages/curl:latest | ||
| 86 | + needs: [sign] | ||
| 87 | + rules: | ||
| 88 | + - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/' | ||
| 89 | + script: | ||
| 90 | + - FILE="${PKG_NAME}-${VERSION}.xpi" | ||
| 91 | + - | | ||
| 92 | + curl --fail --silent --show-error \ | ||
| 93 | + --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \ | ||
| 94 | + --upload-file "out/${FILE}" \ | ||
| 95 | + "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PKG_NAME}/${VERSION}/${FILE}" | ||
| 96 | + | ||
| 97 | +# --------------------------------------------------------------------------- | ||
| 98 | +# Release — crée une Release GitLab avec un lien vers le .xpi (pour les humains). | ||
| 99 | +# --------------------------------------------------------------------------- | ||
| 100 | +release: | ||
| 101 | + stage: publish | ||
| 102 | + image: registry.gitlab.com/gitlab-org/release-cli:latest | ||
| 103 | + needs: [sign, publish] | ||
| 104 | + rules: | ||
| 105 | + - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/' | ||
| 106 | + script: | ||
| 107 | + - echo "Release ${CI_COMMIT_TAG}" | ||
| 108 | + release: | ||
| 109 | + tag_name: '$CI_COMMIT_TAG' | ||
| 110 | + name: 're:group $CI_COMMIT_TAG' | ||
| 111 | + description: 'Version signée disponible sur la page de mise à jour.' | ||
| 112 | + assets: | ||
| 113 | + links: | ||
| 114 | + - name: 're_group ${VERSION} (.xpi signé)' | ||
| 115 | + url: '${PAGES_BASE}/${PKG_NAME}-${VERSION}.xpi' | ||
| 116 | + | ||
| 117 | +# --------------------------------------------------------------------------- | ||
| 118 | +# Pages — reconstruit le site public : miroir de TOUS les .xpi du registry | ||
| 119 | +# + updates.json regénéré depuis la liste complète des versions. | ||
| 120 | +# Aucun état à committer : la source de vérité est le registry. | ||
| 121 | +# --------------------------------------------------------------------------- | ||
| 122 | +pages: | ||
| 123 | + stage: pages | ||
| 124 | + image: alpine:latest | ||
| 125 | + needs: [publish] | ||
| 126 | + rules: | ||
| 127 | + - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/' | ||
| 128 | + script: | ||
| 129 | + - apk add --no-cache curl jq | ||
| 130 | + - mkdir -p public | ||
| 131 | + - ADDON_ID="$(jq -r '.browser_specific_settings.gecko.id' manifest.json)" | ||
| 132 | + # Liste toutes les versions du paquet générique PKG_NAME. | ||
| 133 | + - | | ||
| 134 | + curl --fail --silent --show-error --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \ | ||
| 135 | + "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages?package_type=generic&per_page=100" \ | ||
| 136 | + > packages.json | ||
| 137 | + - VERSIONS="$(jq -r --arg n "$PKG_NAME" '.[] | select(.name==$n) | .version' packages.json | sort -V)" | ||
| 138 | + - echo "[]" > entries.json | ||
| 139 | + - | | ||
| 140 | + for V in $VERSIONS; do | ||
| 141 | + FILE="${PKG_NAME}-${V}.xpi" | ||
| 142 | + curl --fail --silent --show-error --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \ | ||
| 143 | + -o "public/${FILE}" \ | ||
| 144 | + "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PKG_NAME}/${V}/${FILE}" | ||
| 145 | + jq --arg v "$V" --arg link "${PAGES_BASE}/${FILE}" \ | ||
| 146 | + '. += [{"version":$v,"update_link":$link}]' entries.json > entries.tmp | ||
| 147 | + mv entries.tmp entries.json | ||
| 148 | + done | ||
| 149 | + - | | ||
| 150 | + jq -n --arg id "$ADDON_ID" --slurpfile e entries.json \ | ||
| 151 | + '{addons: {($id): {updates: $e[0]}}}' > public/updates.json | ||
| 152 | + - cat public/updates.json | ||
| 153 | + artifacts: | ||
| 154 | + paths: | ||
| 155 | + - public | ||
modified
manifest.json +1 -0 | @@ -8,6 +8,7 @@ | ||
| 8 | 8 | "gecko": { |
| 9 | 9 | "id": "regroup@judu", |
| 10 | 10 | "strict_min_version": "151.0", |
| 11 | + "update_url": "https://juuduu.gitlab.io/re-group-firefox-addon/updates.json", | |
| 11 | 12 | "data_collection_permissions": { |
| 12 | 13 | "required": ["none"] |
| 13 | 14 | } |
| @@ -8,6 +8,7 @@ | |||
| 8 | "gecko": { | 8 | "gecko": { |
| 9 | "id": "regroup@judu", | 9 | "id": "regroup@judu", |
| 10 | "strict_min_version": "151.0", | 10 | "strict_min_version": "151.0", |
| 11 | + "update_url": "https://juuduu.gitlab.io/re-group-firefox-addon/updates.json", | ||
| 11 | "data_collection_permissions": { | 12 | "data_collection_permissions": { |
| 12 | "required": ["none"] | 13 | "required": ["none"] |
| 13 | } | 14 | } |