0712e5b08c
v6.1.3 distribute run (#28579791121) failed all 4 jobs (Homebrew, AUR, Docker Hub, WinGet) because the build workflow took >12 minutes to publish the GitHub release with binary assets, but the distribute workflows only waited 10 minutes (30 iterations x 20s). The race: - Build workflow runs in parallel with Distribute workflow (no `needs:`) - Distribute polls for the .deb/.dmg/.exe assets at the release URL - Old 10-minute hard timeout was tuned for ~5 minute builds - Modern builds (Windows, sanitizers, full Qt) routinely take 20-30 min Bump all 5 wait loops (Docker Hub, AUR, Homebrew, Chocolatey, WinGet) from 30 to 90 iterations, total 30 minutes, and update the error messages to reflect the new timeout. Error messages also gained the "after 30 minutes" suffix for consistency. No change to the trigger conditions or job logic — only the timeout. This is a workflow-only change; no source or CI matrix changes.
671 lines
28 KiB
YAML
671 lines
28 KiB
YAML
name: Distribute Release
|
|
|
|
# Auto-pushes new releases to package managers. Triggers on:
|
|
# - tag push (e.g. v5.9.21) — the normal release flow
|
|
# - workflow_dispatch — manual run for testing or backports
|
|
#
|
|
# Each step that needs a secret checks for it and skips gracefully with a
|
|
# clear warning if it's not set, so the workflow can be merged and tested
|
|
# before secrets are configured.
|
|
|
|
on:
|
|
push:
|
|
tags: ['v*']
|
|
workflow_dispatch:
|
|
inputs:
|
|
version:
|
|
description: 'Override version (e.g. 5.9.21). Leave blank to use tag.'
|
|
required: false
|
|
type: string
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
version:
|
|
name: Resolve version
|
|
runs-on: ubuntu-22.04
|
|
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')
|
|
outputs:
|
|
version: ${{ steps.v.outputs.version }}
|
|
steps:
|
|
- id: v
|
|
run: |
|
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ inputs.version }}" ]; then
|
|
echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
|
|
fi
|
|
- run: echo "Distributing v${{ steps.v.outputs.version }}"
|
|
|
|
docker:
|
|
name: Docker Hub
|
|
needs: version
|
|
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')
|
|
runs-on: ubuntu-22.04
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
env:
|
|
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
VERSION: ${{ needs.version.outputs.version }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
- name: Login to Docker Hub
|
|
run: |
|
|
if [ -z "$DOCKERHUB_TOKEN" ]; then
|
|
echo "::warning::DOCKERHUB_TOKEN secret not set — skipping Docker push. Add it at Settings → Secrets → Actions."
|
|
exit 0
|
|
fi
|
|
echo "$DOCKERHUB_TOKEN" | docker login -u samiahmed7777 --password-stdin
|
|
|
|
- name: Wait for release artifacts
|
|
run: |
|
|
# The Dockerfile downloads the daemon .deb from the release URL.
|
|
# On tag-push the release is created first, but the assets get
|
|
# uploaded a few seconds/minutes later by the build job — without
|
|
# this wait, the Docker build races and fails with curl 22 / 404
|
|
# (saw this on v5.9.24 run #24, dist #24, Docker Hub job
|
|
# step #5 — release was published 8 min after the workflow fired).
|
|
for i in {1..90}; do
|
|
URL="https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}/cryptographic-triangles-daemon_${VERSION}_amd64.deb"
|
|
if curl -fsSL --head "$URL" >/dev/null 2>&1; then
|
|
echo "✓ Release .deb available: $URL"
|
|
exit 0
|
|
fi
|
|
echo " waiting for release v${VERSION} daemon .deb... ($i/90)"
|
|
sleep 20
|
|
done
|
|
echo "::error::Release v${VERSION} daemon .deb never became available after 30 minutes"
|
|
exit 1
|
|
|
|
- name: Build and push
|
|
run: |
|
|
if [ -z "$DOCKERHUB_TOKEN" ]; then exit 0; fi
|
|
docker buildx build \
|
|
--push \
|
|
--tag samiahmed7777/trianglesd:$VERSION \
|
|
--tag samiahmed7777/trianglesd:latest \
|
|
--cache-from type=gha \
|
|
--cache-to type=gha,mode=max \
|
|
--provenance=false \
|
|
./packaging/docker
|
|
|
|
- name: Verify pushed image
|
|
run: |
|
|
if [ -z "$DOCKERHUB_TOKEN" ]; then exit 0; fi
|
|
docker pull samiahmed7777/trianglesd:$VERSION
|
|
echo "--- trianglesd -version ---"
|
|
docker run --rm samiahmed7777/trianglesd:$VERSION trianglesd -version 2>&1 | head -3
|
|
echo "--- triangles-cli getinfo (will fail without RPC, expected) ---"
|
|
docker run --rm samiahmed7777/trianglesd:$VERSION triangles-cli getinfo 2>&1 | head -3
|
|
|
|
aur:
|
|
name: AUR (triangles-qt-bin)
|
|
needs: version
|
|
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')
|
|
runs-on: ubuntu-22.04
|
|
container:
|
|
image: archlinux:latest
|
|
options: --privileged
|
|
env:
|
|
AUR_SSH_KEY: ${{ secrets.AUR_SSH_KEY }}
|
|
VERSION: ${{ needs.version.outputs.version }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Check AUR_SSH_KEY
|
|
run: |
|
|
if [ -z "$AUR_SSH_KEY" ]; then
|
|
echo "::warning::AUR_SSH_KEY secret not set — skipping AUR push. Add it at Settings → Secrets → Actions."
|
|
echo "::warning::The key should be the contents of ~/.ssh/aur_key (private key, not .pub)."
|
|
fi
|
|
|
|
- name: Install build tools + create non-root user
|
|
if: env.AUR_SSH_KEY != ''
|
|
run: |
|
|
pacman -Syu --noconfirm --needed git openssh base-devel python sudo
|
|
# makepkg refuses to run as root — create a build user
|
|
useradd -m -s /bin/bash build
|
|
echo 'build ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
|
|
chown -R build:build "$GITHUB_WORKSPACE"
|
|
|
|
- name: Wait for release artifacts
|
|
if: env.AUR_SSH_KEY != ''
|
|
run: |
|
|
for i in {1..90}; do
|
|
URL="https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}/cryptographic-triangles_${VERSION}_amd64.deb"
|
|
if curl -fsSL --head "$URL" >/dev/null 2>&1; then
|
|
echo "✓ Release .deb available: $URL"
|
|
exit 0
|
|
fi
|
|
echo " waiting for release v${VERSION}... ($i/90)"
|
|
sleep 20
|
|
done
|
|
echo "::error::Release v${VERSION} .deb never became available after 30 minutes"
|
|
exit 1
|
|
|
|
- name: Download source .debs
|
|
if: env.AUR_SSH_KEY != ''
|
|
run: |
|
|
cd /tmp
|
|
curl -fsSL -o full.deb "https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}/cryptographic-triangles_${VERSION}_amd64.deb"
|
|
curl -fsSL -o daemon.deb "https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}/cryptographic-triangles-daemon_${VERSION}_amd64.deb"
|
|
ls -la /tmp/*.deb
|
|
sha256sum /tmp/full.deb /tmp/daemon.deb
|
|
|
|
- name: Update PKGBUILD with version + SHA256s
|
|
if: env.AUR_SSH_KEY != ''
|
|
run: |
|
|
cp "$GITHUB_WORKSPACE/packaging/aur/PKGBUILD" /tmp/PKGBUILD
|
|
chown build:build /tmp/PKGBUILD /tmp/full.deb /tmp/daemon.deb
|
|
sudo -u build bash -c '
|
|
set -e
|
|
cd /tmp
|
|
FULL_SHA=$(sha256sum full.deb | awk "{print \$1}")
|
|
DAEMON_SHA=$(sha256sum daemon.deb | awk "{print \$1}")
|
|
echo "version='"$VERSION"' full=$FULL_SHA daemon=$DAEMON_SHA"
|
|
python3 - <<PYEOF
|
|
import re
|
|
with open("/tmp/PKGBUILD") as f:
|
|
content = f.read()
|
|
content = re.sub(r"^pkgver=.*", "pkgver='"$VERSION"'", content, count=1, flags=re.MULTILINE)
|
|
new_shas = """sha256sums=(
|
|
'"'"'$FULL_SHA'"'"'
|
|
'"'"'$DAEMON_SHA'"'"'
|
|
'"'"'SKIP'"'"'
|
|
)"""
|
|
content = re.sub(r"sha256sums=\(.*?\)", new_shas, content, count=1, flags=re.DOTALL)
|
|
with open("/tmp/PKGBUILD", "w") as f:
|
|
f.write(content)
|
|
PYEOF
|
|
echo "--- updated PKGBUILD (pkgver + sha256sums) ---"
|
|
grep -E "^(pkgver|sha256sums)" /tmp/PKGBUILD
|
|
'
|
|
|
|
- name: Generate .SRCINFO via makepkg
|
|
if: env.AUR_SSH_KEY != ''
|
|
run: |
|
|
cp /tmp/full.deb "/tmp/cryptographic-triangles_${VERSION}_amd64.deb"
|
|
cp /tmp/daemon.deb "/tmp/cryptographic-triangles-daemon_${VERSION}_amd64.deb"
|
|
chown build:build /tmp/PKGBUILD /tmp/cryptographic-triangles-*.deb
|
|
sudo -u build bash -c '
|
|
cd /tmp
|
|
makepkg --printsrcinfo > .SRCINFO
|
|
echo "--- generated .SRCINFO ---"
|
|
cat .SRCINFO
|
|
'
|
|
|
|
- name: Setup SSH key for AUR
|
|
if: env.AUR_SSH_KEY != ''
|
|
run: |
|
|
mkdir -p /home/build/.ssh
|
|
printf '%s\n' "$AUR_SSH_KEY" > /home/build/.ssh/aur_key
|
|
chmod 600 /home/build/.ssh/aur_key
|
|
ssh-keyscan -t ed25519 aur.archlinux.org > /home/build/.ssh/known_hosts 2>/dev/null
|
|
chown -R build:build /home/build/.ssh
|
|
|
|
- name: Clone AUR repo
|
|
if: env.AUR_SSH_KEY != ''
|
|
run: |
|
|
sudo -u build bash -c '
|
|
cd /tmp
|
|
GIT_SSH_COMMAND="ssh -i ~/.ssh/aur_key -o IdentitiesOnly=yes" \
|
|
git clone ssh://aur@aur.archlinux.org/triangles-qt-bin.git
|
|
ls -la /tmp/triangles-qt-bin
|
|
'
|
|
|
|
- name: Stage updated files
|
|
if: env.AUR_SSH_KEY != ''
|
|
run: |
|
|
cp /tmp/PKGBUILD /tmp/triangles-qt-bin/PKGBUILD
|
|
cp /tmp/.SRCINFO /tmp/triangles-qt-bin/.SRCINFO
|
|
cp "$GITHUB_WORKSPACE/packaging/aur/triangles-qt.desktop" /tmp/triangles-qt-bin/triangles-qt.desktop
|
|
chown -R build:build /tmp/triangles-qt-bin
|
|
sudo -u build bash -c '
|
|
cd /tmp/triangles-qt-bin
|
|
git --no-pager diff --stat
|
|
'
|
|
|
|
- name: Commit and push to AUR
|
|
if: env.AUR_SSH_KEY != ''
|
|
run: |
|
|
sudo -u build bash -c '
|
|
cd /tmp/triangles-qt-bin
|
|
git config user.name "Sami Ahmed"
|
|
git config user.email "SamiAhmed7777@users.noreply.github.com"
|
|
git add PKGBUILD .SRCINFO triangles-qt.desktop
|
|
if git diff --cached --quiet; then
|
|
echo "No changes to commit (AUR already at this version)"
|
|
exit 0
|
|
fi
|
|
git commit -m "triangles-qt-bin '"$VERSION"'-1"
|
|
GIT_SSH_COMMAND="ssh -i ~/.ssh/aur_key -o IdentitiesOnly=yes" \
|
|
git push origin master
|
|
'
|
|
|
|
- name: ✓ Summary
|
|
if: always()
|
|
run: |
|
|
if [ -z "$AUR_SSH_KEY" ]; then
|
|
echo "::notice::AUR job was skipped because AUR_SSH_KEY is not set."
|
|
else
|
|
echo "::notice::AUR distribution completed."
|
|
fi
|
|
|
|
homebrew:
|
|
name: Homebrew tap (SamiAhmed7777/homebrew-triangles)
|
|
needs: version
|
|
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')
|
|
runs-on: ubuntu-22.04
|
|
env:
|
|
HOMEBREW_GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_TOKEN }}
|
|
VERSION: ${{ needs.version.outputs.version }}
|
|
steps:
|
|
- name: Check HOMEBREW_GITHUB_TOKEN
|
|
run: |
|
|
if [ -z "$HOMEBREW_GITHUB_TOKEN" ]; then
|
|
echo "::warning::HOMEBREW_GITHUB_TOKEN secret not set — skipping Homebrew push. Add it at Settings → Secrets → Actions."
|
|
echo "::warning::Use a GitHub PAT with 'repo' scope for SamiAhmed7777/homebrew-triangles."
|
|
fi
|
|
|
|
- name: Wait for release artifacts
|
|
if: env.HOMEBREW_GITHUB_TOKEN != ''
|
|
run: |
|
|
for i in {1..90}; do
|
|
URL="https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}/Cryptographic-Triangles-v${VERSION}-macos-arm64.dmg"
|
|
if curl -fsSL --head "$URL" >/dev/null 2>&1; then
|
|
echo "✓ Release .dmg available: $URL"
|
|
exit 0
|
|
fi
|
|
echo " waiting for release v${VERSION}... ($i/90)"
|
|
sleep 20
|
|
done
|
|
echo "::error::Release v${VERSION} macOS .dmg never became available after 30 minutes"
|
|
exit 1
|
|
|
|
- name: Compute macOS .dmg SHA256
|
|
if: env.HOMEBREW_GITHUB_TOKEN != ''
|
|
id: sha
|
|
run: |
|
|
curl -fsSL -o /tmp/triangles.dmg \
|
|
"https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}/Cryptographic-Triangles-v${VERSION}-macos-arm64.dmg"
|
|
SHA=$(sha256sum /tmp/triangles.dmg | awk '{print $1}')
|
|
echo "sha=$SHA" >> $GITHUB_OUTPUT
|
|
echo "macOS .dmg SHA256: $SHA"
|
|
|
|
- name: Clone homebrew-triangles
|
|
if: env.HOMEBREW_GITHUB_TOKEN != ''
|
|
run: |
|
|
git clone https://x-access-token:$HOMEBREW_GITHUB_TOKEN@github.com/SamiAhmed7777/homebrew-triangles.git /tmp/homebrew-triangles
|
|
cd /tmp/homebrew-triangles
|
|
git --no-pager log --oneline | head -3
|
|
|
|
- name: Update Formula and Cask
|
|
if: env.HOMEBREW_GITHUB_TOKEN != ''
|
|
env:
|
|
VERSION: ${{ needs.version.outputs.version }}
|
|
SHA: ${{ steps.sha.outputs.sha }}
|
|
run: |
|
|
cd /tmp/homebrew-triangles
|
|
# Update Casks/cryptographic-triangles.rb
|
|
python3 - <<PYEOF
|
|
import re
|
|
for path, old_v_pat, old_sha_pat in [
|
|
('Casks/cryptographic-triangles.rb', r'^\s*version\s+"[\d.]+"', r'^\s*sha256\s+"[a-f0-9]+"'),
|
|
('Formula/triangles.rb', r'^\s*version\s+"[\d.]+"', r'^\s*sha256\s+"[a-f0-9]+"'),
|
|
]:
|
|
with open(path) as f: content = f.read()
|
|
content = re.sub(old_v_pat, f' version "$VERSION"', content, count=1, flags=re.MULTILINE)
|
|
content = re.sub(old_sha_pat, f' sha256 "$SHA"', content, count=1, flags=re.MULTILINE)
|
|
with open(path, 'w') as f: f.write(content)
|
|
PYEOF
|
|
cat Formula/triangles.rb | head -5
|
|
echo "---"
|
|
cat Casks/cryptographic-triangles.rb | head -5
|
|
git --no-pager diff --stat
|
|
|
|
- name: Commit and push
|
|
if: env.HOMEBREW_GITHUB_TOKEN != ''
|
|
env:
|
|
VERSION: ${{ needs.version.outputs.version }}
|
|
run: |
|
|
cd /tmp/homebrew-triangles
|
|
git config user.name "Sami Ahmed"
|
|
git config user.email "SamiAhmed7777@users.noreply.github.com"
|
|
git add Formula/triangles.rb Casks/cryptographic-triangles.rb
|
|
if git diff --cached --quiet; then
|
|
echo "No changes to commit (Homebrew tap already at this version)"
|
|
exit 0
|
|
fi
|
|
git commit -m "triangles ${VERSION}"
|
|
git push origin main
|
|
|
|
- name: ✓ Summary
|
|
if: always()
|
|
run: |
|
|
if [ -z "$HOMEBREW_GITHUB_TOKEN" ]; then
|
|
echo "::notice::Homebrew job was skipped because HOMEBREW_GITHUB_TOKEN is not set."
|
|
else
|
|
echo "::notice::Homebrew distribution completed."
|
|
fi
|
|
|
|
chocolatey:
|
|
name: Chocolatey (triangles)
|
|
needs: version
|
|
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')
|
|
runs-on: windows-latest
|
|
env:
|
|
CHOCO_API_KEY: ${{ secrets.CHOCO_API_KEY }}
|
|
VERSION: ${{ needs.version.outputs.version }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Check CHOCO_API_KEY + CHOCO_SKIP_WACATAC
|
|
shell: bash
|
|
run: |
|
|
if [ -z "$CHOCO_API_KEY" ]; then
|
|
echo "::warning::CHOCO_API_KEY not set — skipping Chocolatey push."
|
|
fi
|
|
if [ "$CHOCO_SKIP_WACATAC" != "" ]; then
|
|
echo "::warning::CHOCO_SKIP_WACATAC=$CHOCO_SKIP_WACATAC — skipping Chocolatey push (Wacatac still active)."
|
|
fi
|
|
|
|
- name: Wait for release artifacts
|
|
if: env.CHOCO_API_KEY != '' && env.CHOCO_SKIP_WACATAC != ''
|
|
shell: bash
|
|
run: |
|
|
for i in {1..90}; do
|
|
URL="https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}/Cryptographic-Triangles-${VERSION}-win-x64-setup.exe"
|
|
if curl -fsSL --head "$URL" >/dev/null 2>&1; then
|
|
echo "✓ Release .exe available: $URL"
|
|
exit 0
|
|
fi
|
|
echo " waiting for release v${VERSION}... ($i/90)"
|
|
sleep 20
|
|
done
|
|
echo "::error::Release v${VERSION} Windows installer never became available after 30 minutes"
|
|
exit 1
|
|
|
|
- name: Compute installer SHA256
|
|
if: env.CHOCO_API_KEY != '' && env.CHOCO_SKIP_WACATAC != ''
|
|
shell: bash
|
|
id: sha
|
|
run: |
|
|
curl -fsSL -o /tmp/triangles-setup.exe \
|
|
"https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}/Cryptographic-Triangles-${VERSION}-win-x64-setup.exe"
|
|
SHA=$(sha256sum /tmp/triangles-setup.exe | awk '{print $1}')
|
|
echo "sha=$SHA" >> $GITHUB_OUTPUT
|
|
echo "Chocolatey installer SHA256: $SHA"
|
|
|
|
- name: Update nuspec version
|
|
if: env.CHOCO_API_KEY != '' && env.CHOCO_SKIP_WACATAC != ''
|
|
shell: bash
|
|
working-directory: ${{ github.workspace }}/packaging/chocolatey
|
|
run: |
|
|
python3 -c "
|
|
import re
|
|
with open('triangles.nuspec') as f: c = f.read()
|
|
c = re.sub(r'<version>[\d.]+</version>', f'<version>${VERSION}</version>', c)
|
|
with open('triangles.nuspec', 'w') as f: f.write(c)
|
|
print('updated nuspec version to', '${VERSION}')
|
|
"
|
|
grep -E "<version>|<id>" triangles.nuspec
|
|
|
|
- name: Update nuspec version + install script SHA
|
|
if: env.CHOCO_API_KEY != '' && env.CHOCO_SKIP_WACATAC != ''
|
|
shell: bash
|
|
working-directory: ${{ github.workspace }}/packaging/chocolatey
|
|
run: |
|
|
python3 -c "
|
|
import re
|
|
with open('triangles.nuspec') as f: c = f.read()
|
|
c = re.sub(r'<version>[\d.]+</version>', f'<version>${VERSION}</version>', c)
|
|
with open('triangles.nuspec', 'w') as f: f.write(c)
|
|
with open('tools/chocolateyInstall.ps1') as f: c = f.read()
|
|
c = c.replace('__CHECKSUM_PLACEHOLDER__', '${{ steps.sha.outputs.sha }}')
|
|
with open('tools/chocolateyInstall.ps1', 'w') as f: f.write(c)
|
|
print('updated nuspec version + install script checksum')
|
|
"
|
|
grep -E "<version>|<id>" triangles.nuspec
|
|
grep checksum64 tools/chocolateyInstall.ps1
|
|
|
|
- name: Pack Chocolatey package
|
|
if: env.CHOCO_API_KEY != '' && env.CHOCO_SKIP_WACATAC != ''
|
|
shell: pwsh
|
|
working-directory: ${{ github.workspace }}/packaging/chocolatey
|
|
run: |
|
|
choco pack
|
|
Get-ChildItem *.nupkg
|
|
|
|
- name: Push to Chocolatey
|
|
if: env.CHOCO_API_KEY != '' && env.CHOCO_SKIP_WACATAC != ''
|
|
shell: pwsh
|
|
working-directory: ${{ github.workspace }}/packaging/chocolatey
|
|
run: |
|
|
$apiKey = [System.Environment]::GetEnvironmentVariable('CHOCO_API_KEY', 'Process')
|
|
choco apikey add --key="$apiKey" --source='https://push.chocolatey.org/'
|
|
Get-ChildItem *.nupkg | ForEach-Object {
|
|
Write-Host "Pushing $($_.Name)..."
|
|
choco push $_.Name --source='https://push.chocolatey.org/'
|
|
}
|
|
|
|
- name: ✓ Summary
|
|
if: always()
|
|
shell: bash
|
|
run: |
|
|
if [ -z "$CHOCO_API_KEY" ]; then
|
|
echo "::notice::Chocolatey job skipped (CHOCO_API_KEY not set)."
|
|
elif [ -n "$CHOCO_SKIP_WACATAC" ]; then
|
|
echo "::notice::Chocolatey job skipped (Wacatac detection still active). Set CHOCO_SKIP_WACATAC='' and re-run after Microsoft clears the false-positive."
|
|
else
|
|
echo "::notice::Chocolatey push completed (subject to moderator review)."
|
|
fi
|
|
|
|
winget:
|
|
name: WinGet (CryptographicTriangles.TrianglesQt)
|
|
needs: version
|
|
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')
|
|
runs-on: ubuntu-22.04
|
|
env:
|
|
WINGET_TOKEN: ${{ secrets.WINGET_TOKEN }}
|
|
VERSION: ${{ needs.version.outputs.version }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Check WINGET_TOKEN
|
|
run: |
|
|
if [ -z "$WINGET_TOKEN" ]; then
|
|
echo "::warning::WINGET_TOKEN not set — skipping WinGet PR. Add a GitHub PAT with 'public_repo' scope at Settings → Secrets → Actions."
|
|
fi
|
|
|
|
- name: Wait for release artifacts
|
|
if: env.WINGET_TOKEN != ''
|
|
run: |
|
|
for i in {1..90}; do
|
|
URL="https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}/Cryptographic-Triangles-${VERSION}-win-x64-setup.exe"
|
|
if curl -fsSL --head "$URL" >/dev/null 2>&1; then
|
|
echo "✓ Release .exe available: $URL"
|
|
exit 0
|
|
fi
|
|
echo " waiting for release v${VERSION}... ($i/90)"
|
|
sleep 20
|
|
done
|
|
echo "::error::Release v${VERSION} Windows installer never became available after 30 minutes"
|
|
exit 1
|
|
|
|
- name: Compute installer SHA256
|
|
if: env.WINGET_TOKEN != ''
|
|
id: sha
|
|
run: |
|
|
curl -fsSL -o /tmp/triangles-setup.exe \
|
|
"https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}/Cryptographic-Triangles-${VERSION}-win-x64-setup.exe"
|
|
SHA=$(sha256sum /tmp/triangles-setup.exe | awk '{print $1}')
|
|
echo "sha=$SHA" >> $GITHUB_OUTPUT
|
|
echo "WinGet installer SHA256: $SHA"
|
|
|
|
- name: "Pre-flight check for existing failed WinGet PRs"
|
|
if: env.WINGET_TOKEN != ''
|
|
env:
|
|
GH_TOKEN: ${{ secrets.WINGET_TOKEN }}
|
|
run: |
|
|
set -e
|
|
# Don't pile up PRs if previous ones still have author-action-needed flags.
|
|
# winget-pkgs moderators can read repeated unfixed failures as spam.
|
|
# Skip the PR for this release if any existing SamiAhmed7777 PR against
|
|
# microsoft/winget-pkgs has a blocker label.
|
|
echo "Checking existing open PRs from SamiAhmed7777 on microsoft/winget-pkgs..."
|
|
BLOCKING=$(gh api -X GET \
|
|
'repos/microsoft/winget-pkgs/issues?state=open&labels=PullRequest-Error,Needs-Author-Feedback&per_page=30' \
|
|
--jq '.[] | select(.user.login=="SamiAhmed7777") | "#\(.number) [\(.state)] \(.title)"' \
|
|
|| echo "")
|
|
if [ -n "$BLOCKING" ]; then
|
|
echo "::error::Existing WinGet PR(s) with blocker labels — fix or close those first:"
|
|
echo "$BLOCKING"
|
|
echo "::error::Aborting this WinGet submission to avoid piling up failed PRs."
|
|
exit 1
|
|
fi
|
|
echo "✓ No blocker-labelled PRs found — safe to submit."
|
|
|
|
- name: Fork + update WinGet manifest + open PR
|
|
if: env.WINGET_TOKEN != ''
|
|
env:
|
|
GH_TOKEN: ${{ secrets.WINGET_TOKEN }}
|
|
SHA: ${{ steps.sha.outputs.sha }}
|
|
PUBLISHER_INITIAL: c
|
|
PACKAGE_ID: CryptographicTriangles.TrianglesQt
|
|
PACKAGE_SHORT: TrianglesQt
|
|
INSTALLER_URL: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${{ env.VERSION }}/Cryptographic-Triangles-${{ env.VERSION }}-win-x64-setup.exe
|
|
run: |
|
|
set -e
|
|
# Install gh + jq if missing
|
|
which gh >/dev/null 2>&1 || (curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list >/dev/null && sudo apt update && sudo apt install -y gh jq)
|
|
|
|
# Skip if a PR for THIS version already exists (avoid duplicate submissions).
|
|
echo "Checking for existing PR for version ${VERSION}..."
|
|
if gh api 'repos/microsoft/winget-pkgs/pulls?state=open&per_page=30' \
|
|
--jq ".[] | select(.head.ref | startswith(\"triangles-${VERSION}-\")) | .number" \
|
|
| grep -q .; then
|
|
echo "::notice::PR for v${VERSION} already exists — skipping to avoid duplicate."
|
|
exit 0
|
|
fi
|
|
echo "✓ No existing PR for v${VERSION}."
|
|
|
|
VERSION="$VERSION"
|
|
# Path convention (winget-pkgs): lowercase first letter of publisher,
|
|
# then publisher folder (PascalCase), then short package folder name.
|
|
# Example: manifests/c/CryptographicTriangles/TrianglesQt/5.9.20/
|
|
MANIFEST_DIR="manifests/$PUBLISHER_INITIAL/CryptographicTriangles/$PACKAGE_SHORT/$VERSION"
|
|
|
|
# TrianglesQt is built with NSIS (Nullsoft). Standard silent flag is /S.
|
|
# If the installer tech ever changes, update InstallerSwitches here.
|
|
NSIS_SILENT="/S"
|
|
|
|
# 1. Clone the winget-pkgs repo (Sami's fork) — auto-create fork if needed
|
|
echo "Forking microsoft/winget-pkgs..."
|
|
GH_REPO="SamiAhmed7777/winget-pkgs"
|
|
if ! gh repo view "$GH_REPO" >/dev/null 2>&1; then
|
|
gh repo fork microsoft/winget-pkgs --remote=false || true
|
|
fi
|
|
rm -rf winget-pkgs
|
|
git clone --depth 1 "https://x-access-token:${WINGET_TOKEN}@github.com/${GH_REPO}.git" winget-pkgs
|
|
cd winget-pkgs
|
|
git config user.name "Sami Ahmed"
|
|
git config user.email "SamiAhmed7777@users.noreply.github.com"
|
|
|
|
BRANCH="triangles-${VERSION}-${{ github.run_number }}"
|
|
git checkout -b "$BRANCH"
|
|
|
|
mkdir -p "$MANIFEST_DIR"
|
|
|
|
# 2. Generate the three manifest files (winget-pkgs schema 1.12.0)
|
|
#
|
|
# Schema rules (see doc/manifest/schema/1.12.0/*.md and
|
|
# doc/ValidationFailureGuide.md):
|
|
# - version file: PackageIdentifier, PackageVersion, DefaultLocale
|
|
# (NOT PackageLocale — that's the old field name), ManifestType
|
|
# "version", ManifestVersion "1.12.0"
|
|
# - defaultLocale file: Publisher, PackageName, License,
|
|
# ShortDescription are REQUIRED (no Publisher in version file)
|
|
# - installer file: InstallModes array (not "InstallerMode:
|
|
# interactive" — that's the old field name); ManifestVersion 1.12.0
|
|
# - All files: include # yaml-language-server: $schema=... comment
|
|
# for editor + validator support
|
|
|
|
SCHEMA_BASE="https://raw.githubusercontent.com/microsoft/winget-cli/master/schemas/JSON/manifests/v1.12.0"
|
|
|
|
cat > "$MANIFEST_DIR/${PACKAGE_ID}.yaml" <<EOF
|
|
# yaml-language-server: \$schema=https://aka.ms/winget-manifest.version.1.12.0.schema.json
|
|
PackageIdentifier: ${PACKAGE_ID}
|
|
PackageVersion: ${VERSION}
|
|
DefaultLocale: en-US
|
|
ManifestType: version
|
|
ManifestVersion: 1.12.0
|
|
EOF
|
|
|
|
cat > "$MANIFEST_DIR/${PACKAGE_ID}.locale.en-US.yaml" <<EOF
|
|
# yaml-language-server: \$schema=https://aka.ms/winget-manifest.defaultLocale.1.12.0.schema.json
|
|
PackageIdentifier: ${PACKAGE_ID}
|
|
PackageVersion: ${VERSION}
|
|
PackageLocale: en-US
|
|
Publisher: Cryptographic Triangles
|
|
PublisherUrl: https://cryptographic-triangles.org
|
|
PackageName: Cryptographic Triangles Qt Wallet
|
|
License: MIT
|
|
ShortDescription: Privacy-focused cryptocurrency wallet with PoS staking, Tor v3, and encrypted messaging.
|
|
Description: |-
|
|
Cryptographic Triangles (TRI) is a privacy-focused cryptocurrency
|
|
featuring Proof-of-Stake consensus with 33% annual staking rewards,
|
|
Tor v3 onion routing, and built-in encrypted peer-to-peer messaging.
|
|
Originally launched in July 2014, featuring the unique Hash9 algorithm
|
|
(13-step hash cascade).
|
|
ManifestType: defaultLocale
|
|
ManifestVersion: 1.12.0
|
|
EOF
|
|
|
|
cat > "$MANIFEST_DIR/${PACKAGE_ID}.installer.yaml" <<EOF
|
|
# yaml-language-server: \$schema=https://aka.ms/winget-manifest.installer.1.12.0.schema.json
|
|
PackageIdentifier: ${PACKAGE_ID}
|
|
PackageVersion: ${VERSION}
|
|
InstallModes:
|
|
- interactive
|
|
- silent
|
|
InstallerSwitches:
|
|
Silent: /S
|
|
SilentWithProgress: /S
|
|
Installers:
|
|
- Architecture: x64
|
|
InstallerType: exe
|
|
InstallerUrl: ${INSTALLER_URL}
|
|
InstallerSha256: ${SHA}
|
|
ManifestType: installer
|
|
ManifestVersion: 1.12.0
|
|
EOF
|
|
|
|
git add "$MANIFEST_DIR"
|
|
git commit -m "${PACKAGE_ID} version ${VERSION}"
|
|
git push origin "$BRANCH"
|
|
|
|
# 3. Open PR
|
|
gh pr create \
|
|
--repo microsoft/winget-pkgs \
|
|
--head "SamiAhmed7777:${BRANCH}" \
|
|
--base master \
|
|
--title "${PACKAGE_ID} version ${VERSION}" \
|
|
--body "Automated update of ${PACKAGE_ID} to v${VERSION}. Artifacts at ${INSTALLER_URL} (SHA256: ${SHA})."
|
|
|
|
echo "✓ PR opened"
|
|
|
|
- name: ✓ Summary
|
|
if: always()
|
|
run: |
|
|
if [ -z "$WINGET_TOKEN" ]; then
|
|
echo "::notice::WinGet job skipped (WINGET_TOKEN not set)."
|
|
else
|
|
echo "::notice::WinGet PR opened."
|
|
fi
|