fix(ci): sign APT Release files manually instead of via reprepro gpgme
reprepro uses gpgme for signing which fails in CI environments because gpgme cannot access pinentry. Instead, remove SignWith from the reprepro distributions config and sign Release files manually with gpg after reprepro finishes, producing both Release.gpg and InRelease.
This commit is contained in:
parent
160495b84e
commit
80ecaeb567
|
|
@ -259,19 +259,15 @@ jobs:
|
|||
gpg-passphrase: "${{ secrets.RELEASE_GPG_PASSPHRASE }}"
|
||||
gpg-sign-key: "${{ secrets.RELEASE_GPG_SIGN_KEY }}"
|
||||
|
||||
- name: Configure GPG for non-interactive signing
|
||||
run: |
|
||||
echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
|
||||
echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf
|
||||
gpgconf --kill gpg-agent
|
||||
gpg-connect-agent reloadagent /bye
|
||||
|
||||
- name: Export GPG public key
|
||||
run: |
|
||||
mkdir -p dist/repo-output
|
||||
gpg --export --armor 7D061A4AA61436B40713D42EFF054DACD908493A > dist/repo-output/gpg.key
|
||||
|
||||
- name: Generate APT repo metadata
|
||||
env:
|
||||
RELEASE_GPG_KEY: 7D061A4AA61436B40713D42EFF054DACD908493A
|
||||
RELEASE_GPG_PASSPHRASE: ${{ secrets.RELEASE_GPG_PASSPHRASE }}
|
||||
run: |
|
||||
chmod +x ./mage-static
|
||||
./mage-static release:repo-apt
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ Codename: stable
|
|||
Architectures: amd64 arm64 armhf
|
||||
Components: main
|
||||
Description: The Vikunja package repository.
|
||||
SignWith: 7D061A4AA61436B40713D42EFF054DACD908493A
|
||||
|
||||
Origin: dl.vikunja.io
|
||||
Label: Vikunja
|
||||
|
|
@ -12,4 +11,3 @@ Codename: unstable
|
|||
Architectures: amd64 arm64 armhf
|
||||
Components: main
|
||||
Description: The Vikunja unstable package repository.
|
||||
SignWith: 7D061A4AA61436B40713D42EFF054DACD908493A
|
||||
|
|
|
|||
35
magefile.go
35
magefile.go
|
|
@ -1216,7 +1216,9 @@ func repoSuite() string {
|
|||
// RepoApt generates APT repository metadata using reprepro.
|
||||
// It expects .deb files in <DIST>/repo-work/incoming/ and outputs to <DIST>/repo-output/apt/.
|
||||
// The reprepro config is read from build/reprepro-dist-conf.
|
||||
// Signing is done manually after reprepro finishes to avoid gpgme pinentry issues in CI.
|
||||
// Environment: REPO_SUITE controls the target suite (default: "stable").
|
||||
// Environment: RELEASE_GPG_KEY, RELEASE_GPG_PASSPHRASE must be set for signing.
|
||||
func (Release) RepoApt(ctx context.Context) error {
|
||||
mg.Deps(initVars)
|
||||
|
||||
|
|
@ -1256,6 +1258,39 @@ func (Release) RepoApt(ctx context.Context) error {
|
|||
}
|
||||
}
|
||||
|
||||
// Sign Release files manually (reprepro's gpgme signing doesn't work in CI)
|
||||
gpgKey := os.Getenv("RELEASE_GPG_KEY")
|
||||
gpgPassphrase := os.Getenv("RELEASE_GPG_PASSPHRASE")
|
||||
|
||||
releaseFile := filepath.Join(outputBase, "dists", suite, "Release")
|
||||
if _, err := os.Stat(releaseFile); err == nil {
|
||||
// Generate Release.gpg (detached signature)
|
||||
if err := runAndStreamOutput(ctx, "gpg",
|
||||
"--default-key", gpgKey,
|
||||
"--batch", "--yes",
|
||||
"--passphrase", gpgPassphrase,
|
||||
"--pinentry-mode", "loopback",
|
||||
"--detach-sign", "--armor",
|
||||
"-o", releaseFile+".gpg",
|
||||
releaseFile,
|
||||
); err != nil {
|
||||
return fmt.Errorf("signing Release (detached): %w", err)
|
||||
}
|
||||
|
||||
// Generate InRelease (clearsigned)
|
||||
if err := runAndStreamOutput(ctx, "gpg",
|
||||
"--default-key", gpgKey,
|
||||
"--batch", "--yes",
|
||||
"--passphrase", gpgPassphrase,
|
||||
"--pinentry-mode", "loopback",
|
||||
"--clearsign",
|
||||
"-o", filepath.Join(filepath.Dir(releaseFile), "InRelease"),
|
||||
releaseFile,
|
||||
); err != nil {
|
||||
return fmt.Errorf("signing Release (clearsign): %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("APT repo metadata generated in", outputBase)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue