Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,44 @@ jobs:
shell: pwsh
run: .\build\Publish-ConsoleMode.ps1 -Runtime x64 -Target All -Version "${{ steps.version.outputs.version }}"

# Code signing (docs/CODE_SIGNING.md). Off until the SignPath repository variables exist:
# SIGNPATH_ORGANIZATION_ID, SIGNPATH_PROJECT_SLUG, SIGNPATH_POLICY_SLUG, plus the
# SIGNPATH_API_TOKEN secret. Only tag pushes are signed; each request waits for manual approval.
- name: Upload unsigned build for signing
id: unsigned
if: github.event_name == 'push' && vars.SIGNPATH_ORGANIZATION_ID != ''

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition only checks SIGNPATH_ORGANIZATION_ID, so configuring the organization before SIGNPATH_PROJECT_SLUG, SIGNPATH_POLICY_SLUG, or SIGNPATH_API_TOKEN makes the subsequent SignPath action run with incomplete inputs and fail the tagged release. The PR describes signing as gated on all repository variables and the secret; gate all signing steps on the complete configuration, or fail early with a clear setup error before publishing.

Technical details
# Complete SignPath configuration gate

## Affected sites
- `.github/workflows/release.yml:99-122` — the upload, submission, and replacement steps use the organization-only condition.

## Required outcome
- A tagged release must either execute the complete signing path with all required SignPath values or remain on the existing unsigned path; a partially configured repository must not fail during the release.

## Suggested approach
- Use a single job-level or step condition that verifies the organization, project slug, policy slug, and token are all configured, with an explicit setup failure if partial configuration is detected.

uses: actions/upload-artifact@v4
with:
name: unsigned-${{ steps.version.outputs.version }}
path: |
dist/ConsoleMode-Setup-x64.exe
dist/ConsoleMode-Portable-x64.exe
if-no-files-found: error

- name: Sign with SignPath
if: github.event_name == 'push' && vars.SIGNPATH_ORGANIZATION_ID != ''
uses: signpath/github-action-submit-signing-request@v2
with:
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
organization-id: ${{ vars.SIGNPATH_ORGANIZATION_ID }}
project-slug: ${{ vars.SIGNPATH_PROJECT_SLUG }}
signing-policy-slug: ${{ vars.SIGNPATH_POLICY_SLUG }}
github-artifact-id: ${{ steps.unsigned.outputs.artifact-id }}
wait-for-completion: true
wait-for-completion-timeout-in-seconds: 3600
output-artifact-directory: dist-signed

- name: Use the signed files
if: github.event_name == 'push' && vars.SIGNPATH_ORGANIZATION_ID != ''
shell: pwsh
run: |
foreach ($name in "ConsoleMode-Setup-x64.exe", "ConsoleMode-Portable-x64.exe") {
$signed = Join-Path "dist-signed" $name
if (-not (Test-Path -LiteralPath $signed)) { throw "SignPath did not return $name" }
if ((Get-AuthenticodeSignature -LiteralPath $signed).Status -ne "Valid") { throw "$name is not validly signed" }
Copy-Item -LiteralPath $signed -Destination (Join-Path "dist" $name) -Force
}

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,4 @@ All the details in the [release notes](https://github.com/lippdev/consolemode/re
- **Feedback:** the button next to Settings in the app, or [this form](https://github.com/lippdev/consolemode/issues/new?template=feedback.yml). A ⭐ helps other couch gamers find the project.
- Antivirus may flag the bundled helper tools; the source is all here.

MIT License · [Third-party notices](THIRD_PARTY_NOTICES.md)
MIT License · [Third-party notices](THIRD_PARTY_NOTICES.md) · [Code signing policy](docs/CODE_SIGNING.md)
2 changes: 1 addition & 1 deletion README.pt-BR.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,4 @@ Todos os detalhes nas [notas da versão](https://github.com/lippdev/consolemode/
- **Feedback:** o botão ao lado de Ajustes no app, ou [este formulário](https://github.com/lippdev/consolemode/issues/new?template=feedback.yml). Uma ⭐ ajuda outros jogadores de sofá a encontrar o projeto.
- Alguns antivírus podem acusar as ferramentas auxiliares incluídas; o código está todo aqui.

Licença MIT · [Avisos de terceiros](THIRD_PARTY_NOTICES.md)
Licença MIT · [Avisos de terceiros](THIRD_PARTY_NOTICES.md) · [Política de assinatura de código](docs/CODE_SIGNING.md)
40 changes: 40 additions & 0 deletions docs/CODE_SIGNING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Code signing policy

> **Status:** application to the SignPath Foundation open source program is pending.
> Until it is approved, releases are not signed and this policy describes how they will be.

Free code signing provided by [SignPath.io](https://about.signpath.io/), certificate by [SignPath Foundation](https://signpath.org/).

## What gets signed

Only binaries built from this repository's source by the [Release workflow](../.github/workflows/release.yml)
on GitHub Actions, from a `v*` tag:

- `ConsoleMode-Setup-x64.exe` (installer)
- `ConsoleMode-Portable-x64.exe` (portable)

Nothing built on a developer machine is signed.

## Team roles

| Role | Members |
|------|---------|
| Committers and reviewers | [Filipe Moreira (@lippdev)](https://github.com/lippdev) |
| Approvers | [Filipe Moreira (@lippdev)](https://github.com/lippdev) |

Pull requests from people outside this list, and from automated agents, are reviewed by a committer
before merge, and every pull request must pass the CI build. Each signing request is approved
manually by an approver. All members use multi-factor authentication on GitHub and SignPath.

## Privacy

Console Mode does not collect or send telemetry. It connects to the internet only to:

- check for new versions through the public GitHub Releases API (`api.github.com`), without
sending any personal data, and download an update when the user accepts it;
- open pages in the user's browser when the user asks for it (the feedback form on GitHub,
the releases page, links to other apps).

Settings, the display backup and the log stay on the user's PC, in `%LOCALAPPDATA%\ConsoleMode`
(installer) or `ConsoleMode_Data` next to the executable (portable). The installer version can be
removed from Windows Settings → Apps; the portable version by deleting its file and folder.
Loading