v2.0.0-rc.3 #62
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish release to WinGet | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Release tag to publish to winget (e.g. v1.4.0)" | |
| required: true | |
| type: string | |
| # GITHUB_TOKEN ne sert qu'en lecture : l'action lit la release et télécharge | |
| # komac. Tout ce qui écrit (branche de la fork, PR sur winget-pkgs) passe par | |
| # WINGET_ACC_TOKEN. | |
| permissions: | |
| contents: read | |
| jobs: | |
| publish: | |
| runs-on: windows-latest | |
| # La condition de configuration a QUITTÉ ce `if`, et c'est tout l'objet du | |
| # changement. `vars.WINGET_IDENTIFIER != ''` ici rendait le job `skipped`, et un | |
| # job sauté est vert : les huit dernières releases, v1.8.0 comprise, ont toutes | |
| # « réussi » sans rien publier, et #148 est resté ouvert deux semaines parce que | |
| # rien, nulle part, ne le disait. Même famille que le glob zsync mort de | |
| # build.yml — un garde qui ne fait rien en silence ne garde rien. | |
| # | |
| # Le job démarre donc toujours, et c'est une étape qui annonce l'absence de | |
| # configuration. Le coût est une minute de runner par release ; le gain est que | |
| # « pas publié » devienne visible dans le résumé du run. | |
| if: github.event_name == 'workflow_dispatch' || !github.event.release.prerelease | |
| env: | |
| IDENTIFIER: ${{ vars.WINGET_IDENTIFIER }} | |
| # `secrets` n'est PAS un contexte lisible depuis un `if`, ni au niveau du job ni | |
| # au niveau de l'étape — seul `env` l'est. D'où ce booléen-en-chaîne, qui expose | |
| # la présence du token sans jamais exposer sa valeur. | |
| HAS_TOKEN: ${{ secrets.WINGET_ACC_TOKEN != '' }} | |
| # La fork de winget-pkgs où komac crée sa branche — getopenscreen/winget-pkgs, | |
| # celle qui a publié 1.9.6 et 1.10.0. C'est déjà la valeur par défaut de | |
| # `fork-user`, mais écrite ici elle est partagée : le contrôle ci-dessous vise | |
| # la fork même où komac écrira, pas une supposition. | |
| FORK_OWNER: ${{ github.repository_owner }} | |
| steps: | |
| # N'annonce que ce que cette étape teste — la variable et le secret — et ce que ce | |
| # secret doit être. Un PAT fine-grained N'EST PAS supporté | |
| # (vedantmgoyal9/winget-releaser#172) : komac sait committer avec, pas ouvrir la | |
| # PR sur microsoft/winget-pkgs. Les deux autres prérequis sont en place et vérifiés | |
| # ailleurs : la fork par l'étape suivante, et l'existence d'une première version | |
| # dans winget-pkgs par l'action elle-même, qui part d'un manifeste existant pour | |
| # écrire le suivant — 1.9.2 y est entrée à la main, via `wingetcreate`. | |
| - name: Report that winget publishing is not configured | |
| if: env.IDENTIFIER == '' || env.HAS_TOKEN != 'true' | |
| run: | | |
| echo "::warning title=winget publishing skipped::Nothing was published to winget. Needs (1) the repository variable WINGET_IDENTIFIER, currently ${{ env.IDENTIFIER == '' && 'UNSET' || 'set' }}; and (2) the secret WINGET_ACC_TOKEN, currently ${{ env.HAS_TOKEN == 'true' && 'set' || 'UNSET' }} — a CLASSIC PAT with the public_repo and workflow scopes, from an account that can push to ${{ env.FORK_OWNER }}/winget-pkgs; fine-grained tokens are not supported. See technical-documentation/engineering/release-and-secrets.md and https://github.com/getopenscreen/openscreen/issues/757" | |
| # Le piège qui a coûté 1.11.0 à 1.13.0 (#757), et que ni l'action ni komac ne | |
| # documentent : komac crée sa branche dans la fork à la pointe du master | |
| # d'upstream, et GitHub refuse cette ref à un PAT sans le scope `workflow` dès | |
| # qu'elle porte un fichier de .github/workflows qu'aucune branche de la fork n'a | |
| # à l'identique. Upstream retouche ses workflows depuis le 26/08 — neuf commits | |
| # en trois semaines — et la fork ne se resynchronise jamais seule. komac n'en dit | |
| # que « does not have the correct permissions to execute CreateRef », qui accuse | |
| # le compte, pourtant admin de la fork, au lieu du scope qui manque. | |
| # | |
| # D'où ce contrôle, en lecture seule, avant komac : les scopes classiques du | |
| # token (l'en-tête X-OAuth-Scopes, qu'un PAT fine-grained ne porte pas), son | |
| # droit de push sur la fork, puis `workflow` — exigé seulement si les workflows | |
| # de la fork divergent de ceux d'upstream, puisqu'un « Sync fork » manuel suffit | |
| # alors, jusqu'à la retouche suivante. | |
| - name: Check that WINGET_ACC_TOKEN can create komac's branch in the fork | |
| if: env.IDENTIFIER != '' && env.HAS_TOKEN == 'true' | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ secrets.WINGET_ACC_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| fork="$FORK_OWNER/winget-pkgs" | |
| fail() { | |
| echo "::error title=WINGET_ACC_TOKEN cannot publish::$1" | |
| exit 1 | |
| } | |
| if ! response=$(gh api --include user 2>&1); then | |
| fail "GitHub rejected WINGET_ACC_TOKEN: $(tail -n 1 <<< "$response")" | |
| fi | |
| # Le nom de l'en-tête seul est retiré : les scopes eux-mêmes contiennent des | |
| # « : » (read:org, repo:status), et un découpage sur « : » lirait repo:status | |
| # comme repo. | |
| scopes=$(tr -d '\r' <<< "$response" | awk 'tolower($0) ~ /^x-oauth-scopes:/ { sub(/^[^:]*:[ \t]*/, ""); print }') | |
| scopes=${scopes// /} | |
| echo "WINGET_ACC_TOKEN classic scopes: ${scopes:-none}" | |
| if [[ ",$scopes," != *,public_repo,* && ",$scopes," != *,repo,* ]]; then | |
| fail "WINGET_ACC_TOKEN lacks the public_repo scope (classic scopes: ${scopes:-none}). It must be a classic PAT with public_repo to open the pull request on microsoft/winget-pkgs; a fine-grained PAT carries no classic scopes and is not supported." | |
| fi | |
| if ! push=$(gh api "repos/$fork" --jq '.permissions.push' 2>&1); then | |
| fail "WINGET_ACC_TOKEN cannot read $fork, the fork komac creates its branch in: $(tail -n 1 <<< "$push")" | |
| fi | |
| if [[ "$push" != true ]]; then | |
| fail "The account behind WINGET_ACC_TOKEN has no push access to $fork, the fork komac creates its branch in." | |
| fi | |
| if [[ ",$scopes," == *,workflow,* ]]; then | |
| echo "OK: public_repo and workflow scopes, push access to $fork." | |
| exit 0 | |
| fi | |
| workflows_tree() { | |
| gh api "repos/$1/contents/.github?ref=master" --jq '.[] | select(.name == "workflows") | .sha' | |
| } | |
| # Comme les appels ci-dessus : sous `set -e`, une substitution qui échoue | |
| # (404, limite de débit, réseau) terminerait l'étape sans annotation. | |
| if ! upstream=$(workflows_tree microsoft/winget-pkgs 2>&1); then | |
| fail "Could not read .github/workflows on microsoft/winget-pkgs, so this check cannot tell whether the workflow scope is needed: $(tail -n 1 <<< "$upstream")" | |
| fi | |
| if ! ours=$(workflows_tree "$fork" 2>&1); then | |
| fail "Could not read .github/workflows on $fork, so this check cannot tell whether the workflow scope is needed: $(tail -n 1 <<< "$ours")" | |
| fi | |
| if [[ "$upstream" != "$ours" ]]; then | |
| fail "WINGET_ACC_TOKEN lacks the workflow scope, and $fork is behind microsoft/winget-pkgs on .github/workflows. komac creates its branch at upstream master, and GitHub refuses that ref to a PAT without workflow; komac reports it as 'does not have the correct permissions to execute CreateRef' (#757). Add the workflow scope to this classic PAT at https://github.com/settings/tokens (its value does not change, so the secret stays as is), or press Sync fork on https://github.com/$fork, which only holds until upstream edits a workflow again." | |
| fi | |
| echo "OK: public_repo scope, push access to $fork, and its .github/workflows match upstream's, so this run does not need the workflow scope." | |
| # Épinglé sur le SHA de v2 : un tag git est mutable, et cette action tierce | |
| # reçoit WINGET_ACC_TOKEN. Un tag repointé suffirait à exfiltrer le token | |
| # sans qu'aucun changement n'apparaisse ici. Pour bouger de version, | |
| # re-résoudre le tag et remplacer le SHA explicitement. | |
| - uses: vedantmgoyal9/winget-releaser@4ffc7888bffd451b357355dc214d43bb9f23917e # v2 | |
| if: env.IDENTIFIER != '' && env.HAS_TOKEN == 'true' | |
| with: | |
| identifier: ${{ vars.WINGET_IDENTIFIER }} | |
| # Matches the Windows installer asset attached to each release, | |
| # e.g. "Openscreen.Setup.1.5.0.exe". | |
| installers-regex: 'Setup\..*\.exe$' | |
| release-tag: ${{ inputs.tag || github.event.release.tag_name }} | |
| token: ${{ secrets.WINGET_ACC_TOKEN }} | |
| fork-user: ${{ env.FORK_OWNER }} |