Skip to content

E2E Live Release

E2E Live Release #72

Workflow file for this run

name: E2E Live Release
on:
workflow_run:
workflows: [Release]
types: [completed]
branches: [main]
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
inputs:
version:
description: 'Release tag to test (e.g. v1.2.3). Leave empty for latest.'
required: false
default: ''
promote:
description: 'Promote to latest after E2E passes'
type: boolean
default: false
pull_request:
paths:
- '.github/workflows/e2e.yml'
jobs:
resolve-version:
name: Resolve version
runs-on: ubuntu-latest
if: github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success'
outputs:
version: ${{ steps.resolve.outputs.version }}
is_prerelease: ${{ steps.resolve.outputs.is_prerelease }}
should_promote: ${{ steps.resolve.outputs.should_promote }}
steps:
- name: Download release-version artifact
id: download
if: github.event_name == 'workflow_run'
continue-on-error: true
uses: actions/download-artifact@v4
with:
name: release-version
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
- name: Resolve version and flags
id: resolve
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: dpkay-io/gitreg
EVENT_NAME: ${{ github.event_name }}
INPUT_VERSION: ${{ inputs.version }}
INPUT_PROMOTE: ${{ inputs.promote }}
DOWNLOAD_OUTCOME: ${{ steps.download.outcome }}
run: |
VERSION=""
if [ "$EVENT_NAME" = "workflow_run" ]; then
if [ "$DOWNLOAD_OUTCOME" = "success" ] && [ -f version.txt ]; then
VERSION="$(cat version.txt | tr -d '[:space:]')"
fi
elif [ "$EVENT_NAME" = "workflow_dispatch" ] && [ -n "$INPUT_VERSION" ]; then
VERSION="$INPUT_VERSION"
fi
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
IS_PRERELEASE="false"
if [ -n "$VERSION" ]; then
IS_PRERELEASE=$(gh release view "$VERSION" --json isPrerelease --jq '.isPrerelease // false' 2>/dev/null || echo "false")
fi
echo "is_prerelease=${IS_PRERELEASE}" >> "$GITHUB_OUTPUT"
SHOULD_PROMOTE="false"
if [ "$IS_PRERELEASE" = "true" ]; then
if [ "$EVENT_NAME" = "workflow_run" ] || [ "$INPUT_PROMOTE" = "true" ]; then
SHOULD_PROMOTE="true"
fi
fi
echo "should_promote=${SHOULD_PROMOTE}" >> "$GITHUB_OUTPUT"
e2e-native:
name: Native (${{ matrix.os }})
needs: [resolve-version]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-14, windows-2022]
steps:
- name: Install (macOS)
if: startsWith(matrix.os, 'macos')
run: |
export GITREG_VERSION="${{ needs.resolve-version.outputs.version }}"
curl -sSf https://raw.githubusercontent.com/dpkay-io/gitreg/main/install.sh | bash
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install (Windows)
if: startsWith(matrix.os, 'windows')
shell: powershell
run: |
$env:GITREG_VERSION = "${{ needs.resolve-version.outputs.version }}"
irm https://raw.githubusercontent.com/dpkay-io/gitreg/main/install.ps1 | iex
$installDir = Join-Path $env:LOCALAPPDATA 'Programs\gitreg'
echo $installDir >> $env:GITHUB_PATH
- name: Verify version
run: gitreg system version
- name: Info
shell: bash
run: |
gitreg commands
gitreg init || true
- name: Register and list
shell: bash
run: |
mkdir -p "$RUNNER_TEMP/repo-a"
git -C "$RUNNER_TEMP/repo-a" init -q
gitreg hook --path "$RUNNER_TEMP/repo-a"
gitreg ls | grep "repo-a"
gitreg ls --json | grep "repo-a"
gitreg repo ls | grep "repo-a"
gitreg repo ls --json | grep "repo-a"
- name: Tag and untag
shell: bash
run: |
gitreg repo tag "$RUNNER_TEMP/repo-a" e2e-tag
gitreg ls | grep "e2e-tag"
gitreg repo untag "$RUNNER_TEMP/repo-a" e2e-tag
! gitreg ls | grep "e2e-tag"
gitreg tag "$RUNNER_TEMP/repo-a" alias-tag
gitreg ls | grep "alias-tag"
gitreg untag "$RUNNER_TEMP/repo-a" alias-tag
! gitreg ls | grep "alias-tag"
- name: Git command
shell: bash
run: gitreg git all status
- name: Live integrator - registered (macOS)
if: startsWith(matrix.os, 'macos')
shell: bash
run: |
SOCK="$RUNNER_TEMP/gitreg-e2e-reg.sock"
rm -f "$SOCK"
mkdir -p "$RUNNER_TEMP/repo-reg-live"
git -C "$RUNNER_TEMP/repo-reg-live" init -q
RPATH=$(python3 -c "import os,sys; print(os.path.realpath(sys.argv[1]))" "$RUNNER_TEMP/repo-reg-live")
cat > "$RUNNER_TEMP/listener_reg.py" << 'PYEOF'
import socket, json, os, sys
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(os.environ['GITREG_E2E_SOCK'])
sock.listen(1)
sock.settimeout(5)
conn, _ = sock.accept()
raw = b''
while True:
c = conn.recv(4096)
if not c:
break
raw += c
p = json.loads(raw.decode().strip())
assert p['event'] == 'registered', repr(p)
assert 'repo-reg-live' in p['data']['path'], repr(p)
print('OK registered')
PYEOF
export GITREG_E2E_SOCK="$SOCK"
python3 "$RUNNER_TEMP/listener_reg.py" &
LISTENER_PID=$!
sleep 0.3
gitreg integrator register --app e2e-reg --event registered --socket "$SOCK"
gitreg hook --path "$RPATH"
sleep 0.5
wait $LISTENER_PID
gitreg integrator rm --app e2e-reg
- name: Live integrator - registered (Windows)
if: startsWith(matrix.os, 'windows')
shell: powershell
run: |
$pipeName = 'gitreg-e2e-reg'
$pipe = New-Object System.IO.Pipes.NamedPipeServerStream(
$pipeName,
[System.IO.Pipes.PipeDirection]::In,
1,
[System.IO.Pipes.PipeTransmissionMode]::Byte,
[System.IO.Pipes.PipeOptions]::Asynchronous,
65536,
65536
)
$ar = $pipe.BeginWaitForConnection($null, $null)
$repoDir = "$env:RUNNER_TEMP\repo-reg-live"
New-Item -ItemType Directory -Path $repoDir -Force | Out-Null
git -C $repoDir init -q
gitreg integrator register --app e2e-reg --event registered --socket "\\.\pipe\$pipeName"
gitreg hook --path $repoDir
if (-not $ar.AsyncWaitHandle.WaitOne(5000)) {
Write-Error "Timeout waiting for registered event"
exit 1
}
$pipe.EndWaitForConnection($ar)
$reader = New-Object System.IO.StreamReader($pipe)
$line = $reader.ReadLine()
$payload = $line | ConvertFrom-Json
if ($payload.event -ne 'registered') {
Write-Error "Expected 'registered', got '$($payload.event)'"
exit 1
}
Write-Host "OK: $($payload.event)"
$reader.Close()
$pipe.Close()
gitreg integrator rm --app e2e-reg
- name: Live integrator - tagged (macOS)
if: startsWith(matrix.os, 'macos')
shell: bash
run: |
SOCK="$RUNNER_TEMP/gitreg-e2e-tag.sock"
rm -f "$SOCK"
RPATH=$(python3 -c "import os,sys; print(os.path.realpath(sys.argv[1]))" "$RUNNER_TEMP/repo-a")
cat > "$RUNNER_TEMP/listener_tag.py" << 'PYEOF'
import socket, json, os, sys
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(os.environ['GITREG_E2E_SOCK'])
sock.listen(1)
sock.settimeout(5)
conn, _ = sock.accept()
raw = b''
while True:
c = conn.recv(4096)
if not c:
break
raw += c
p = json.loads(raw.decode().strip())
assert p['event'] == 'tagged', repr(p)
assert p['data']['tag'] == 'live-tag', repr(p)
print('OK tagged')
PYEOF
export GITREG_E2E_SOCK="$SOCK"
python3 "$RUNNER_TEMP/listener_tag.py" &
LISTENER_PID=$!
sleep 0.3
gitreg integrator register --app e2e-tagged --event tagged --socket "$SOCK"
gitreg repo tag "$RPATH" live-tag
sleep 0.5
wait $LISTENER_PID
gitreg repo untag "$RPATH" live-tag
gitreg integrator rm --app e2e-tagged
- name: Live integrator - tagged (Windows)
if: startsWith(matrix.os, 'windows')
shell: powershell
run: |
$pipeName = 'gitreg-e2e-tag'
$pipe = New-Object System.IO.Pipes.NamedPipeServerStream(
$pipeName,
[System.IO.Pipes.PipeDirection]::In,
1,
[System.IO.Pipes.PipeTransmissionMode]::Byte,
[System.IO.Pipes.PipeOptions]::Asynchronous,
65536,
65536
)
$ar = $pipe.BeginWaitForConnection($null, $null)
$repoDir = "$env:RUNNER_TEMP\repo-a"
gitreg integrator register --app e2e-tagged --event tagged --socket "\\.\pipe\$pipeName"
gitreg repo tag $repoDir live-tag
if (-not $ar.AsyncWaitHandle.WaitOne(5000)) {
Write-Error "Timeout waiting for tagged event"
exit 1
}
$pipe.EndWaitForConnection($ar)
$reader = New-Object System.IO.StreamReader($pipe)
$line = $reader.ReadLine()
$payload = $line | ConvertFrom-Json
if ($payload.event -ne 'tagged') {
Write-Error "Expected 'tagged', got '$($payload.event)'"
exit 1
}
if ($payload.data.tag -ne 'live-tag') {
Write-Error "Expected tag 'live-tag', got '$($payload.data.tag)'"
exit 1
}
Write-Host "OK: $($payload.event)"
$reader.Close()
$pipe.Close()
gitreg repo untag $repoDir live-tag
gitreg integrator rm --app e2e-tagged
- name: Scan
shell: bash
run: |
mkdir -p "$RUNNER_TEMP/scan-dir/nested-repo"
git -C "$RUNNER_TEMP/scan-dir/nested-repo" init -q
gitreg repo scan "$RUNNER_TEMP/scan-dir"
gitreg ls | grep "nested-repo"
gitreg scan "$RUNNER_TEMP/scan-dir"
- name: Prune
shell: bash
run: |
mkdir -p "$RUNNER_TEMP/prune-repo-1"
git -C "$RUNNER_TEMP/prune-repo-1" init -q
gitreg hook --path "$RUNNER_TEMP/prune-repo-1"
rm -rf "$RUNNER_TEMP/prune-repo-1"
gitreg repo prune
! gitreg ls | grep "prune-repo-1"
mkdir -p "$RUNNER_TEMP/prune-repo-2"
git -C "$RUNNER_TEMP/prune-repo-2" init -q
gitreg hook --path "$RUNNER_TEMP/prune-repo-2"
rm -rf "$RUNNER_TEMP/prune-repo-2"
gitreg prune
! gitreg ls | grep "prune-repo-2"
- name: Remove
shell: bash
run: |
gitreg rm "$RUNNER_TEMP/scan-dir/nested-repo"
! gitreg ls | grep "nested-repo"
gitreg repo rm "$RUNNER_TEMP/repo-a"
! gitreg ls | grep "repo-a"
- name: Autoscan (macOS)
if: startsWith(matrix.os, 'macos')
run: |
mkdir -p "$HOME/git/autoscan-e2e"
git -C "$HOME/git/autoscan-e2e" init -q
gitreg autoscan
gitreg ls | grep "autoscan-e2e"
- name: Autoscan (Windows)
if: startsWith(matrix.os, 'windows')
shell: powershell
run: |
$repoDir = Join-Path $HOME "source\repos\autoscan-e2e"
New-Item -ItemType Directory -Path $repoDir -Force | Out-Null
git -C $repoDir init -q
gitreg autoscan
gitreg ls | Select-String "autoscan-e2e"
- name: Config
shell: bash
run: |
gitreg config alias
gitreg config autoprune --enable
gitreg config autoprune --disable
mkdir -p "$RUNNER_TEMP/excluded"
gitreg config exclude add "$RUNNER_TEMP/excluded"
gitreg config exclude ls | grep "excluded"
gitreg config exclude rm "$RUNNER_TEMP/excluded"
! gitreg config exclude ls | grep "excluded"
- name: Integrator CLI
shell: bash
run: |
gitreg integrator events
gitreg integrator ls
gitreg integrator register --app cli-app --event registered --socket "$RUNNER_TEMP/cli.sock"
gitreg integrator ls | grep "cli-app"
gitreg integrator block --app cli-app
gitreg integrator unblock --app cli-app
gitreg integrator unregister --app cli-app --event registered
gitreg integrator rm --app cli-app
! gitreg integrator ls | grep "cli-app"
- name: Uninstall
shell: bash
run: echo "UNINSTALL" | gitreg system uninstall
e2e-linux-docker:
name: Linux Docker (${{ matrix.arch }})
needs: [resolve-version]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
arch: [amd64, arm64]
steps:
- name: Set up QEMU
if: matrix.arch == 'arm64'
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq qemu-user-static binfmt-support
- name: Test in Docker
run: |
docker run --rm --platform linux/${{ matrix.arch }} \
-e "GITREG_VERSION=${{ needs.resolve-version.outputs.version }}" \
ubuntu:22.04 bash -c "
set -eo pipefail
apt-get update -qq
apt-get install -y -qq curl git bash tar ca-certificates socat > /dev/null
curl -sSf https://raw.githubusercontent.com/dpkay-io/gitreg/main/install.sh | bash
export PATH=\"\$HOME/.local/bin:\$PATH\"
gitreg system version
gitreg commands
gitreg init || true
mkdir -p /tmp/repo-a && git -C /tmp/repo-a init -q
gitreg hook --path /tmp/repo-a
gitreg ls | grep repo-a
gitreg ls --json | grep repo-a
gitreg repo ls | grep repo-a
gitreg repo ls --json | grep repo-a
gitreg repo tag /tmp/repo-a e2e-tag
gitreg ls | grep e2e-tag
gitreg repo untag /tmp/repo-a e2e-tag
! gitreg ls | grep e2e-tag
gitreg tag /tmp/repo-a alias-tag
gitreg ls | grep alias-tag
gitreg untag /tmp/repo-a alias-tag
! gitreg ls | grep alias-tag
gitreg git all status
socat -u UNIX-LISTEN:/tmp/e2e-reg.sock STDOUT > /tmp/e2e-reg-out &
LRPID=\$!
sleep 0.3
gitreg integrator register --app e2e-reg --event registered --socket /tmp/e2e-reg.sock
mkdir -p /tmp/repo-reg-live && git -C /tmp/repo-reg-live init -q
gitreg hook --path /tmp/repo-reg-live
sleep 0.5
wait \$LRPID || true
grep -q registered /tmp/e2e-reg-out
grep -q repo-reg-live /tmp/e2e-reg-out
gitreg integrator rm --app e2e-reg
socat -u UNIX-LISTEN:/tmp/e2e-tag.sock STDOUT > /tmp/e2e-tag-out &
LTPID=\$!
sleep 0.3
gitreg integrator register --app e2e-tagged --event tagged --socket /tmp/e2e-tag.sock
gitreg repo tag /tmp/repo-a live-tag
sleep 0.5
wait \$LTPID || true
grep -q tagged /tmp/e2e-tag-out
grep -q live-tag /tmp/e2e-tag-out
gitreg repo untag /tmp/repo-a live-tag
gitreg integrator rm --app e2e-tagged
mkdir -p /tmp/scan-dir/nested-repo && git -C /tmp/scan-dir/nested-repo init -q
gitreg repo scan /tmp/scan-dir
gitreg ls | grep nested-repo
gitreg scan /tmp/scan-dir
mkdir -p /tmp/prune-repo-1 && git -C /tmp/prune-repo-1 init -q
gitreg hook --path /tmp/prune-repo-1
rm -rf /tmp/prune-repo-1
gitreg repo prune
! gitreg ls | grep prune-repo-1
mkdir -p /tmp/prune-repo-2 && git -C /tmp/prune-repo-2 init -q
gitreg hook --path /tmp/prune-repo-2
rm -rf /tmp/prune-repo-2
gitreg prune
! gitreg ls | grep prune-repo-2
gitreg rm /tmp/scan-dir/nested-repo
! gitreg ls | grep nested-repo
gitreg repo rm /tmp/repo-a
! gitreg ls | grep repo-a
mkdir -p \"\$HOME/git/autoscan-e2e\" && git -C \"\$HOME/git/autoscan-e2e\" init -q
gitreg autoscan
gitreg ls | grep autoscan-e2e
gitreg config alias
gitreg config autoprune --enable
gitreg config autoprune --disable
mkdir -p /tmp/excluded
gitreg config exclude add /tmp/excluded
gitreg config exclude ls | grep excluded
gitreg config exclude rm /tmp/excluded
! gitreg config exclude ls | grep excluded
gitreg integrator events
gitreg integrator ls
gitreg integrator register --app cli-app --event registered --socket /tmp/cli.sock
gitreg integrator ls | grep cli-app
gitreg integrator block --app cli-app
gitreg integrator unblock --app cli-app
gitreg integrator unregister --app cli-app --event registered
gitreg integrator rm --app cli-app
! gitreg integrator ls | grep cli-app
echo UNINSTALL | gitreg system uninstall
"
promote:
name: Promote to latest
needs: [resolve-version, e2e-native, e2e-linux-docker]
if: needs.resolve-version.outputs.should_promote == 'true'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Promote release to latest
run: gh release edit "${{ needs.resolve-version.outputs.version }}" --prerelease=false --latest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: dpkay-io/gitreg