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
398 changes: 398 additions & 0 deletions .github/workflows/release.yml

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ English | [Português (Brasil)](README.pt-BR.md)

Download the installer or the ZIP from the [latest release](https://github.com/leoars/PostgresManagementStudio/releases), run it, then use **Connect** and **New Query**. Backup/restore needs the PostgreSQL client tools (`pg_dump`, `pg_restore`, `psql`) of the same major version as the server. Details: [setup guide](docs/en/getting-started.md).

#### Windows SmartScreen warning

PGMS releases are not code-signed yet, so Windows may show "Windows protected your PC" the first time you run the installer or `PGMS.exe`. Choose **More info** and then **Run anyway**. Before doing so, confirm the download matches the checksums published with the release:

```powershell
Get-FileHash .\PGMS-* -Algorithm SHA256
```

Compare the hashes with `SHA256SUMS.txt` and the installer's `.sha256` file in the release. v0.1.0-alpha.1 was built on the maintainer's machine, so it has checksums but no build provenance attestation; releases produced by the [release workflow](.github/workflows/release.yml) can additionally be verified with `gh attestation verify`. Code signing through the SignPath Foundation open source program is planned.

### Build from source

For development: Windows x64, PowerShell 7 and the .NET SDK selected by [global.json](global.json) (`10.0.400`, latest installed patch in that feature band). PostgreSQL 17/18 and matching-major tools are needed for database tests and backup/restore.
Expand Down
10 changes: 10 additions & 0 deletions README.pt-BR.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@

Baixe o instalador ou o ZIP na [release mais recente](https://github.com/leoars/PostgresManagementStudio/releases), execute e use **Connect** e **New Query**. Backup/restore exige as ferramentas cliente do PostgreSQL (`pg_dump`, `pg_restore`, `psql`) da mesma versão principal do servidor. Detalhes: [guia de preparação](docs/pt-BR/getting-started.md).

#### Aviso do SmartScreen do Windows

As releases do PGMS ainda não são assinadas digitalmente, então o Windows pode mostrar "O Windows protegeu o computador" na primeira execução do instalador ou do `PGMS.exe`. Clique em **Mais informações** e depois em **Executar assim mesmo**. Antes disso, confirme que o download corresponde aos checksums publicados com a release:

```powershell
Get-FileHash .\PGMS-* -Algorithm SHA256
```

Compare os hashes com o `SHA256SUMS.txt` e com o arquivo `.sha256` do instalador na release. A v0.1.0-alpha.1 foi compilada na máquina do mantenedor, então tem checksums mas não tem atestado de proveniência de build; releases geradas pelo [workflow de release](.github/workflows/release.yml) podem ser verificadas também com `gh attestation verify`. A assinatura de código pelo programa open source da SignPath Foundation está planejada.

### Compilar a partir do código

Para desenvolvimento: Windows x64, PowerShell 7 e SDK .NET selecionado por [global.json](global.json) (`10.0.400`, com o patch mais recente instalado nessa faixa). PostgreSQL 17/18 e ferramentas da mesma versão principal são necessários para testes com banco e backup/restore.
Expand Down
10 changes: 10 additions & 0 deletions docs/en/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ Choose only one focused suite per invocation. Some fixtures intentionally create

When publishing a release, upload one `SHA256SUMS.txt` that covers every binary asset (ZIP, PowerShell installer and graphical installer EXE) instead of per-asset checksum files, and do not replace assets or checksums after publication; publish a new tag instead.

## Release

Release binaries come from [release.yml](../../.github/workflows/release.yml) on a GitHub-hosted Windows runner, not from a developer machine. Before tagging, declare the same version in `Directory.Build.props`, `installer/release.json` (`Version`, `NumericVersion`, `Milestone`) and `src/PGMS.Desktop/BuildInfo.cs`; the workflow fails when the tag (`v` plus the version) and these files disagree. Pushing a tag `v*`, or running the workflow manually with the tag name, publishes the ReadyToRun payload with `Publish.ps1 -SelfContained` under deterministic build settings, runs `Verify-Package.ps1`, `Test-Package.ps1` and `Test-PackageGuides.ps1`, creates the ZIP with `New-PackageArchive.ps1`, installs the pinned, hash-verified Inno Setup 7.1.1 in portable mode and builds the installer with `Build-GraphicalInstaller.ps1 -SkipFrozenManifest` (the frozen manifest hash in `release.json` describes a payload built locally; in CI the payload comes from the run itself, so only milestone and product version are compared). It then writes `SHA256SUMS.txt`, attests build provenance for the ZIP and the installer and creates a **draft** pre-release with the notes from `docs/en` and `docs/pt-BR`. Publishing the draft, and any change to an existing release, remains a manual decision; a release that already exists for the tag makes the workflow fail. A tag or manual run whose name carries build metadata (`v0.1.0-alpha.1+ci.1`) produces a test draft that must be deleted after review, together with the test tag; manual runs are only possible after the workflow exists on `main`. Verify an asset produced by the workflow with:

```powershell
gh attestation verify .\<asset> --repo leoars/PostgresManagementStudio
```

The jobs `sign-binaries` and `sign-installer` are reserved for the SignPath Foundation open source program and stay skipped until the repository variable `SIGNPATH_ENABLED` is `true`; they then require the secret `SIGNPATH_API_TOKEN` and the variables `SIGNPATH_ORGANIZATION_ID`, `SIGNPATH_PROJECT_SLUG`, `SIGNPATH_SIGNING_POLICY_SLUG` and `SIGNPATH_ARTIFACT_CONFIGURATION_SLUG`. Application binaries are signed before they enter the ZIP and the installer, the installer is signed last, and checksums and attestations cover the final files.

## Change workflow

Read [CONTRIBUTING.md](../../CONTRIBUTING.md) and [AGENTS.md](../../AGENTS.md). Keep public English/pt-BR guides synchronized. Report validation actually run and its limitations. Record relevant changes and validation in the pull request. GitHub Actions ([build.yml](../../.github/workflows/build.yml)) runs `Build.ps1 -Configuration Release` and `Test-PublicDocumentation.ps1` on Windows for pushes and pull requests; database and WPF suites are not run there and must be reported manually. Dependabot opens weekly pull requests for NuGet packages and pinned actions. Never commit profiles, tokens, private keys, dumps, build outputs or local acceptance artifacts. Gitleaks can scan history with `gitleaks git . --log-opts="--all --full-history" --redact=100`. This source repository starts with a new history and no historical secret-scan exceptions.
10 changes: 10 additions & 0 deletions docs/en/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ English | [Português (Brasil)](../pt-BR/getting-started.md)

[Download v0.1.0-alpha.1](https://github.com/leoars/PostgresManagementStudio/releases/tag/v0.1.0-alpha.1): [graphical installer](graphical-installer.md), portable ZIP or PowerShell 7 installer. The graphical installer offers current-user and all-users modes and does not require PowerShell. See [release notes](release-notes.md).

### Windows SmartScreen warning

PGMS releases are not code-signed yet, so Windows may show "Windows protected your PC" the first time you run the installer or `PGMS.exe`. Choose **More info** and then **Run anyway**. Before doing so, confirm the download matches the checksums published with the release:

```powershell
Get-FileHash .\PGMS-* -Algorithm SHA256
```

Compare the hashes with `SHA256SUMS.txt` and the installer's `.sha256` file in the release. v0.1.0-alpha.1 was built on the maintainer's machine, so it has checksums but no build provenance attestation; releases produced by the [release workflow](../../.github/workflows/release.yml) can additionally be verified with `gh attestation verify` (see [development](development.md)). Code signing through the SignPath Foundation open source program is planned.

## Requirements

PGMS targets Windows x64. Building requires PowerShell 7 and a .NET 10 SDK compatible with [global.json](../../global.json): 10.0.400 with latest-patch roll-forward. Dependencies are pinned in NuGet lockfiles. The M1008 package was built with SDK 10.0.403 and bundles .NET/WPF 10.0.14; a rebuild may use different installed runtime packs.
Expand Down
2 changes: 1 addition & 1 deletion docs/en/graphical-installer.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The executable is unsigned; SmartScreen reputation and a clean Windows VM have n

## Build and test

Use the official [Inno Setup 7.1.1 x64 compiler](https://jrsoftware.org/isdl.php), retaining its license. Extract the existing release ZIP into `artifacts/M1008-win-x64`. The builder checks every payload file, the frozen manifest and application version, and refuses an existing output directory. A local application rebuild may have a different manifest and is intentionally refused by this release-specific builder. Update the release configuration for a future frozen release.
Use the official [Inno Setup 7.1.1 x64 compiler](https://jrsoftware.org/isdl.php), retaining its license. Extract the existing release ZIP into `artifacts/M1008-win-x64`. The builder checks every payload file, the frozen manifest and application version, and refuses an existing output directory. A local application rebuild may have a different manifest and is intentionally refused by this release-specific builder. Update the release configuration for a future frozen release. The [release workflow](../../.github/workflows/release.yml) passes `-SkipFrozenManifest` because it builds the payload itself; milestone and product version are still enforced, and the frozen hash remains required for local builds.

```powershell
./scripts/Build-GraphicalInstaller.ps1 -PackagePath artifacts/M1008-win-x64 -CompilerPath 'C:\Tools\Inno Setup 7\ISCC.exe'
Expand Down
10 changes: 10 additions & 0 deletions docs/pt-BR/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ Escolha apenas uma suíte focada por execução. Algumas fixtures criam junction

Ao publicar uma release, envie um único `SHA256SUMS.txt` cobrindo todos os assets binários (ZIP, instalador PowerShell e EXE do instalador gráfico) em vez de arquivos de checksum por asset, e não substitua assets ou checksums após a publicação; publique uma nova tag.

## Release

Os binários de release saem do [release.yml](../../.github/workflows/release.yml) em um runner Windows hospedado pelo GitHub, não de uma máquina de desenvolvedor. Antes de criar a tag, declare a mesma versão em `Directory.Build.props`, `installer/release.json` (`Version`, `NumericVersion`, `Milestone`) e `src/PGMS.Desktop/BuildInfo.cs`; o workflow falha quando a tag (`v` mais a versão) e esses arquivos divergem. Um push de tag `v*`, ou a execução manual do workflow com o nome da tag, publica o payload ReadyToRun com `Publish.ps1 -SelfContained` em build determinístico, roda `Verify-Package.ps1`, `Test-Package.ps1` e `Test-PackageGuides.ps1`, cria o ZIP com `New-PackageArchive.ps1`, instala o Inno Setup 7.1.1 fixado e conferido por hash em modo portátil e compila o instalador com `Build-GraphicalInstaller.ps1 -SkipFrozenManifest` (o hash de manifesto congelado em `release.json` descreve um payload compilado localmente; no CI o payload vem da própria execução, então só marco e versão do produto são comparados). Em seguida grava `SHA256SUMS.txt`, atesta a proveniência do ZIP e do instalador e cria uma pré-release em **rascunho** com as notas de `docs/en` e `docs/pt-BR`. Publicar o rascunho, e qualquer alteração em release existente, continua decisão manual; uma release já existente para a tag faz o workflow falhar. Uma tag ou execução manual cujo nome traga metadados de build (`v0.1.0-alpha.1+ci.1`) gera um rascunho de teste que deve ser apagado após a revisão, junto com a tag de teste; execuções manuais só são possíveis depois que o workflow existir na `main`. Verifique um asset gerado pelo workflow com:

```powershell
gh attestation verify .\<asset> --repo leoars/PostgresManagementStudio
```

Os jobs `sign-binaries` e `sign-installer` estão reservados ao programa open source da SignPath Foundation e permanecem pulados até a variável de repositório `SIGNPATH_ENABLED` valer `true`; então exigem o secret `SIGNPATH_API_TOKEN` e as variáveis `SIGNPATH_ORGANIZATION_ID`, `SIGNPATH_PROJECT_SLUG`, `SIGNPATH_SIGNING_POLICY_SLUG` e `SIGNPATH_ARTIFACT_CONFIGURATION_SLUG`. Os binários do aplicativo são assinados antes de entrar no ZIP e no instalador, o instalador é assinado por último, e checksums e atestados cobrem os arquivos finais.

## Fluxo de alteração

Leia [CONTRIBUTING.pt-BR.md](../../CONTRIBUTING.pt-BR.md) e [AGENTS.md](../../AGENTS.md). Sincronize guias públicos inglês/pt-BR. Informe validação realmente executada e limitações. Registre mudanças relevantes e validação no pull request. O GitHub Actions ([build.yml](../../.github/workflows/build.yml)) executa `Build.ps1 -Configuration Release` e `Test-PublicDocumentation.ps1` no Windows em pushes e pull requests; as suítes de banco e WPF não rodam lá e devem ser relatadas manualmente. O Dependabot abre pull requests semanais para pacotes NuGet e actions fixadas. Nunca versione perfis, tokens, chaves privadas, dumps, saídas de build ou artefatos locais de aceitação. Gitleaks examina o histórico com `gitleaks git . --log-opts="--all --full-history" --redact=100`. Este repositório de fonte começa com histórico novo e sem exceções históricas da varredura.
10 changes: 10 additions & 0 deletions docs/pt-BR/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@

[Baixar v0.1.0-alpha.1](https://github.com/leoars/PostgresManagementStudio/releases/tag/v0.1.0-alpha.1): [instalador gráfico](graphical-installer.md), ZIP portátil ou instalador PowerShell 7. O instalador gráfico oferece modos por usuário e para todos, dispensando PowerShell. Veja [notas da versão](release-notes.md).

### Aviso do SmartScreen do Windows

As releases do PGMS ainda não são assinadas digitalmente, então o Windows pode mostrar "O Windows protegeu o computador" na primeira execução do instalador ou do `PGMS.exe`. Clique em **Mais informações** e depois em **Executar assim mesmo**. Antes disso, confirme que o download corresponde aos checksums publicados com a release:

```powershell
Get-FileHash .\PGMS-* -Algorithm SHA256
```

Compare os hashes com o `SHA256SUMS.txt` e com o arquivo `.sha256` do instalador na release. A v0.1.0-alpha.1 foi compilada na máquina do mantenedor, então tem checksums mas não tem atestado de proveniência de build; releases geradas pelo [workflow de release](../../.github/workflows/release.yml) podem ser verificadas também com `gh attestation verify` (veja [desenvolvimento](development.md)). A assinatura de código pelo programa open source da SignPath Foundation está planejada.

## Pré-requisitos

O PGMS é destinado a Windows x64. Compilar exige PowerShell 7 e SDK.NET10 compatível com [global.json](../../global.json): 10.0.400 com roll-forward para o patch mais recente. Dependências são fixadas nos lockfiles NuGet. O pacote M1008 foi compilado com SDK 10.0.403 e inclui .NET/WPF 10.0.14; recompilar pode usar outros runtime packs instalados.
Expand Down
2 changes: 1 addition & 1 deletion docs/pt-BR/graphical-installer.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ O executável não tem assinatura digital; reputação SmartScreen e VM Windows

## Compilar e testar

Use o [compilador oficial Inno Setup 7.1.1 x64](https://jrsoftware.org/isdl.php), preservando sua licença. Extraia o ZIP existente da release em `artifacts/M1008-win-x64`. O builder confere cada arquivo, o manifesto congelado e a versão do aplicativo, recusando diretório de saída existente. Uma recompilação local pode produzir outro manifesto e é intencionalmente recusada por este builder específico da release. Atualize a configuração para uma futura release congelada.
Use o [compilador oficial Inno Setup 7.1.1 x64](https://jrsoftware.org/isdl.php), preservando sua licença. Extraia o ZIP existente da release em `artifacts/M1008-win-x64`. O builder confere cada arquivo, o manifesto congelado e a versão do aplicativo, recusando diretório de saída existente. Uma recompilação local pode produzir outro manifesto e é intencionalmente recusada por este builder específico da release. Atualize a configuração para uma futura release congelada. O [workflow de release](../../.github/workflows/release.yml) passa `-SkipFrozenManifest` porque compila o próprio payload; marco e versão do produto continuam exigidos, e o hash congelado segue obrigatório em builds locais.

```powershell
./scripts/Build-GraphicalInstaller.ps1 -PackagePath artifacts/M1008-win-x64 -CompilerPath 'C:\Tools\Inno Setup 7\ISCC.exe'
Expand Down
10 changes: 7 additions & 3 deletions scripts/Build-GraphicalInstaller.ps1
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
param(
[Parameter(Mandatory)][string]$PackagePath,
[Parameter(Mandatory)][string]$CompilerPath,
[string]$OutputDirectory
[string]$OutputDirectory,
# CI builds the payload from the tagged source, so its manifest hash is not known before the build;
# the switch skips only the frozen-hash comparison and keeps milestone and product version checks.
[switch]$SkipFrozenManifest
)
$ErrorActionPreference = 'Stop'
. (Join-Path $PSScriptRoot 'PackageTools.ps1')
Expand All @@ -10,7 +13,8 @@ $release = Get-Content (Join-Path $root 'installer/release.json') -Raw | Convert
$verified = Test-PgmsPackage $PackagePath
$package = (Get-Item -LiteralPath $PackagePath).FullName
if ($verified.Mode -ne 'SelfContained' -or $verified.Milestone -cne $release.Milestone) { throw 'Wrong release package.' }
if ((Get-FileHash (Join-Path $package 'package-manifest.json')).Hash -cne $release.ManifestSha256) { throw 'Release manifest does not match the frozen payload.' }
$manifestHash = (Get-FileHash (Join-Path $package 'package-manifest.json')).Hash
if (!$SkipFrozenManifest -and $manifestHash -cne $release.ManifestSha256) { throw 'Release manifest does not match the frozen payload.' }
if ([Diagnostics.FileVersionInfo]::GetVersionInfo((Join-Path $package 'PGMS.dll')).ProductVersion -cne $release.Version) { throw 'Wrong product version.' }
$compiler = (Get-Item -LiteralPath $CompilerPath).FullName
if ((Get-AuthenticodeSignature -LiteralPath $compiler).Status -ne 'Valid') { throw 'Compiler signature is not valid.' }
Expand All @@ -34,4 +38,4 @@ if ($LASTEXITCODE -ne 0) { throw "ISCC failed with exit code $LASTEXITCODE. Fail
$exe = Join-Path $output "PGMS-$($release.Version)-Setup-x64.exe"
$hash = (Get-FileHash -LiteralPath $exe -Algorithm SHA256).Hash
"$hash $([IO.Path]::GetFileName($exe))" | Set-Content -LiteralPath "$exe.sha256" -Encoding ascii
[pscustomobject]@{ Installer = $exe; Sha256 = $hash; CompilerVersion = $compilerVersion; PayloadManifest = $release.ManifestSha256 }
[pscustomobject]@{ Installer = $exe; Sha256 = $hash; CompilerVersion = $compilerVersion; PayloadManifest = $manifestHash; FrozenManifestChecked = !$SkipFrozenManifest }