Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 37f8b6bee9 | |||
| d3bf9767f7 | |||
| 8fb10cfa94 | |||
| ab710e48bd | |||
| b70a65d18b | |||
| 8659e181c1 | |||
| fc2c609f9c | |||
| 7c183f9b51 | |||
| 4ab3e731a1 | |||
| b47191d0e7 | |||
| cbbe0d523c | |||
| 5996880e1f | |||
| b7399d7b57 | |||
| c8816bc3c0 | |||
| 6030864125 | |||
| a0aeedb796 | |||
| 5f4de58149 | |||
| 1412d00696 | |||
| ed25954c6c |
@@ -8,7 +8,13 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runson: [ubuntu-latest, macos-latest, windows-latest]
|
||||
runson: [
|
||||
ubuntu-latest,
|
||||
ubuntu-20.04,
|
||||
macos-latest,
|
||||
windows-latest,
|
||||
windows-2019
|
||||
]
|
||||
uses: ./.github/workflows/actions-sync-e2e-test-called.yml
|
||||
with:
|
||||
runson: ${{ matrix.runson }}
|
||||
|
||||
@@ -3,14 +3,64 @@ on:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
CI:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Lint
|
||||
run: docker-compose run --rm lint
|
||||
- name: Test
|
||||
run: docker-compose run --rm test
|
||||
- name: E2E
|
||||
run: docker-compose run --rm test-build
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.21
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@v4
|
||||
with:
|
||||
version: v1.54.2
|
||||
unit-test:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.21
|
||||
- name: Unit Tests
|
||||
run: ./script/test
|
||||
e2e-test:
|
||||
needs: unit-test
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
platform: [linux]
|
||||
arch: [amd64, arm64]
|
||||
exclude:
|
||||
# Exclude Windows AMD64 because it's not supported
|
||||
- platform: windows
|
||||
arch: amd64
|
||||
|
||||
steps:
|
||||
- name: Setup QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.21
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build Binary for ${{ matrix.platform }}-${{ matrix.arch }}
|
||||
run: |
|
||||
if [[ "${{ matrix.platform }}" == "linux" ]]; then
|
||||
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
||||
fi
|
||||
|
||||
GOOS=${{ matrix.platform }} GOARCH=${{ matrix.arch }} go build -o bin/actions-sync-${{ matrix.platform }}-${{ matrix.arch }} main.go
|
||||
|
||||
- name: Run End-to-End Tests for ${{ matrix.platform }}-${{ matrix.arch }}
|
||||
run: ./script/test-ci bin/actions-sync-${{ matrix.platform }}-${{ matrix.arch }}
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
- name: Set CURRENT_TAG
|
||||
run: echo "GORELEASER_CURRENT_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@f09f1a7bee7ae6b5153daf4e8c63cc8ce8c7e7d5
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
with:
|
||||
version: latest
|
||||
args: release --clean
|
||||
|
||||
+2
-4
@@ -15,10 +15,8 @@ linters:
|
||||
- govet
|
||||
- unparam
|
||||
run:
|
||||
tests: true
|
||||
skip-files:
|
||||
- ".*_test\\.go$"
|
||||
modules-download-mode: vendor
|
||||
tests: true
|
||||
modules-download-mode: vendor
|
||||
issues:
|
||||
exclude-rules:
|
||||
- path: test/github.go
|
||||
|
||||
+23
-15
@@ -1,16 +1,24 @@
|
||||
project_name: gh
|
||||
|
||||
project_name: actions/actions-sync
|
||||
builds:
|
||||
- <<: &build_defaults
|
||||
binary: bin/actions-sync
|
||||
id: macos
|
||||
goos: [darwin]
|
||||
goarch: [amd64, arm64]
|
||||
- <<: *build_defaults
|
||||
id: linux
|
||||
goos: [linux]
|
||||
goarch: [amd64, arm64]
|
||||
- <<: *build_defaults
|
||||
id: windows
|
||||
goos: [windows]
|
||||
goarch: [amd64]
|
||||
- id: build
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
binary: bin/actions-sync
|
||||
ignore:
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
release:
|
||||
github:
|
||||
owner: actions
|
||||
name: actions-sync
|
||||
# Create the release as a draft so it can be tested before being published
|
||||
# To test, go to the Actions tab and run the "Actions Sync E2E Sanity Test" workflow
|
||||
draft: true
|
||||
|
||||
|
||||
+23
-23
@@ -1,23 +1,23 @@
|
||||
version: "3.5"
|
||||
services:
|
||||
lint:
|
||||
image: lint
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.cibuild
|
||||
entrypoint:
|
||||
- script/lint
|
||||
test:
|
||||
image: test
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.cibuild
|
||||
entrypoint:
|
||||
- script/test
|
||||
test-build:
|
||||
image: test-build
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.cibuild
|
||||
entrypoint:
|
||||
- script/test-build
|
||||
# version: "3.5"
|
||||
# services:
|
||||
# lint:
|
||||
# image: lint
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: Dockerfile.cibuild
|
||||
# entrypoint:
|
||||
# - script/lint
|
||||
# test:
|
||||
# image: test
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: Dockerfile.cibuild
|
||||
# entrypoint:
|
||||
# - script/test
|
||||
# test-build:
|
||||
# image: test-build
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: Dockerfile.cibuild
|
||||
# entrypoint:
|
||||
# - script/test-build
|
||||
|
||||
@@ -4,7 +4,7 @@ if($IsLinux) {
|
||||
} elseif ($IsWindows) {
|
||||
$file_postfix = "windows_amd64"
|
||||
} elseif ($IsMacOS) {
|
||||
$file_postfix = "darwin_amd64"
|
||||
$file_postfix = "darwin_arm64"
|
||||
}
|
||||
|
||||
# Download release to test
|
||||
|
||||
+1
-1
@@ -7,4 +7,4 @@ test -z "${DEBUG:-}" || {
|
||||
set -x
|
||||
}
|
||||
|
||||
go build -o bin/actions-sync main.go
|
||||
go build -o bin/actions-sync main.go
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
script/build
|
||||
#script/build
|
||||
|
||||
OUTPUT=$(mktemp)
|
||||
RESULT=-1
|
||||
|
||||
Executable
+426
@@ -0,0 +1,426 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#script/build
|
||||
|
||||
# if the first argument is missing then print usage and exit
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $1 <path to actions-sync binary>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ACTIONS_SYNC_BINARY=$1
|
||||
|
||||
OUTPUT=$(mktemp)
|
||||
RESULT=-1
|
||||
|
||||
SRC_GIT_DAEMON_PORT=9419
|
||||
SRC_GIT_DAEMON_OUTPUT=$(mktemp)
|
||||
SRC_GIT_DAEMON_PID=-1
|
||||
|
||||
DEST_GIT_DAEMON_PORT=9420
|
||||
DEST_GIT_DAEMON_OUTPUT=$(mktemp)
|
||||
DEST_GIT_DAEMON_PID=-1
|
||||
|
||||
DEST_API_PORT=8081
|
||||
DEST_API_OUTPUT=$(mktemp)
|
||||
DEST_API_PID=-1
|
||||
trap "after_suite" EXIT
|
||||
trap "after_suite" SIGINT
|
||||
|
||||
function test_version() {
|
||||
version "version shouldn't require any flags"
|
||||
|
||||
echo "all version tests passed"
|
||||
}
|
||||
|
||||
function test_pull() {
|
||||
# Pull new repo
|
||||
setup_src "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
setup_cache
|
||||
pull --repo-name "org/repo" "pulling new repo"
|
||||
assert_cache_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "pulling new repo org/repo"
|
||||
|
||||
echo "all pull tests passed successfully"
|
||||
}
|
||||
|
||||
function test_push() {
|
||||
# Push with a new change to main
|
||||
setup_cache "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
|
||||
push "pushing new commit to main"
|
||||
assert_dest_sha "org/repo" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org/repo:heads/main to new commit"
|
||||
|
||||
# Push a non-linear change
|
||||
setup_cache "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
setup_dest "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
|
||||
push "pushing to an old commit to main"
|
||||
assert_dest_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "updating heads/main to an old commit"
|
||||
|
||||
# Push with no changes to main
|
||||
setup_cache "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
push "pushing no changes to main"
|
||||
assert_dest_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "leaving org/repo:heads/main at existing commit"
|
||||
|
||||
# Push multiple branches
|
||||
setup_cache "org/repo:heads/change:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
||||
"org/repo:heads/nochange:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
setup_dest "org/repo:heads/change:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
||||
"org/repo:heads/nochange:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
|
||||
push "pushing multiple branches"
|
||||
assert_dest_sha "org/repo" "heads/change" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org/repo:heads/change to new commit"
|
||||
assert_dest_sha "org/repo" "heads/nochange" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "leaving org/repo:heads/nochange at existing commit"
|
||||
|
||||
# Pushing multiple branches and tags
|
||||
setup_cache "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
||||
"org/repo:tags/v1:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
||||
"org/repo:tags/v1:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
|
||||
push "pushing multiple branches and tags"
|
||||
assert_dest_sha "org/repo" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org/repo:heads/main to new commit"
|
||||
assert_dest_sha "org/repo" "tags/v1" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org/repo:tags/v1 to new commit"
|
||||
|
||||
# Pushing multiple repositories
|
||||
setup_cache "org1/repo1:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
||||
"org1/repo2:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
||||
"org1/repo2:tags/v1:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
||||
"org2/repo1:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_dest "org1/repo1:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
||||
"org1/repo2:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
||||
"org1/repo2:tags/v1:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
||||
"org2/repo1:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
|
||||
push "pushing multiple repositories"
|
||||
assert_dest_sha "org1/repo1" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org1/repo1:heads/main to new commit"
|
||||
assert_dest_sha "org1/repo2" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org1/repo2:heads/main to new commit"
|
||||
assert_dest_sha "org1/repo2" "tags/v1" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org1/repo2:tags/v1 to new commit"
|
||||
assert_dest_sha "org2/repo1" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org2/repo1:tags/v1 to new commit"
|
||||
|
||||
# Honor --repo-name flag, ignore other cache entries
|
||||
setup_cache "org/repo1:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
||||
"org/repo2:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_dest "org/repo1:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
||||
"org/repo2:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
|
||||
push2args --repo-name "org/repo1" "pushing only one of the repos in the cache"
|
||||
assert_dest_sha "org/repo1" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org/repo1 passed in repo flag"
|
||||
assert_dest_sha "org/repo2" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "org/repo2 not updated despite cache"
|
||||
|
||||
# Push to pre-existing org
|
||||
setup_cache "org-already-exists/new-repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_dest "org-already-exists/new-repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
|
||||
push "pushing to existing org"
|
||||
assert_dest_sha "org-already-exists/new-repo" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org-already-exists/new-repo"
|
||||
|
||||
# Push to pre-existing repo
|
||||
setup_cache "org-already-exists/repo-already-exists:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_dest "org-already-exists/repo-already-exists:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
|
||||
push "pushing to existing repo"
|
||||
assert_dest_sha "org-already-exists/repo-already-exists" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org-already-exists/repo-already-exists"
|
||||
|
||||
# Push to repo in user's account
|
||||
setup_cache "monalisa/new-repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_dest "monalisa/new-repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
|
||||
push "pushing to authenticated user's account"
|
||||
assert_dest_sha "monalisa/new-repo" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating monalisa/new-repo"
|
||||
|
||||
# Push to GHAE with impersonation
|
||||
setup_cache "org-already-exists/ghae-repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_dest "org-already-exists/ghae-repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
push_impersonation "ghae-admin" "pushing to GHAE repo"
|
||||
|
||||
# Push to GHES with impersonation
|
||||
setup_cache "org-already-exists/ghes-repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_dest "org-already-exists/ghes-repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
push_impersonation "ghes-admin" "pushing to GHES repo"
|
||||
|
||||
echo "all push tests passed successfully"
|
||||
}
|
||||
|
||||
function test_sync() {
|
||||
# Sync no change without cached
|
||||
setup_src "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
setup_cache
|
||||
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
sync --repo-name "org/repo" "syncing a new commit in an uncached repo"
|
||||
assert_dest_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "syncing no changes without cache"
|
||||
|
||||
# Sync a new commit without cache
|
||||
setup_src "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_cache
|
||||
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
sync --repo-name "org/repo" "syncing a new commit in an uncached repo"
|
||||
assert_dest_sha "org/repo" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "syncing a new commit without cache"
|
||||
|
||||
# Sync no change with uncached
|
||||
setup_src "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
setup_cache "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
sync --repo-name "org/repo" "syncing a new commit in an uncached repo"
|
||||
assert_dest_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "syncing no changes with cache"
|
||||
|
||||
# Sync a new commit with cache
|
||||
setup_src "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_cache "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
sync --repo-name "org/repo" "syncing a new commit in an uncached repo"
|
||||
assert_dest_sha "org/repo" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "syncing a new commit with cache"
|
||||
|
||||
# Sync a non-linear change without cache
|
||||
setup_src "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
setup_cache
|
||||
setup_dest "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
|
||||
sync --repo-name "org/repo" "syncing an old commit in an uncached repo"
|
||||
assert_dest_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "syncing heads/main to an old commit without cache"
|
||||
|
||||
# Sync a non-linear change with cache
|
||||
setup_src "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
setup_cache "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_dest "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
|
||||
sync --repo-name "org/repo" "syncing an old commit in an cached repo"
|
||||
assert_dest_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "syncing heads/main to an old commit with cache"
|
||||
|
||||
# Sync to a different repo
|
||||
setup_src "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_cache
|
||||
setup_dest "org2/repo2:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
|
||||
sync --repo-name "org/repo:org2/repo2" "syncing org/repo aliased to org2/repo2"
|
||||
assert_dest_sha "org2/repo2" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "syncing org/repo aliased to org2/repo2"
|
||||
|
||||
# Honor --repo-name flag, ignore other cache entries
|
||||
setup_cache "org/repo1:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
||||
"org/repo2:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
||||
setup_dest "org/repo1:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
||||
"org/repo2:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
||||
|
||||
sync --repo-name "org/repo1" "syncing only one of the repos in the cache"
|
||||
assert_dest_sha "org/repo1" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org/repo1 passed in repo flag"
|
||||
assert_dest_sha "org/repo2" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "org/repo2 not updated despite cache"
|
||||
|
||||
echo "all sync tests passed successfully"
|
||||
}
|
||||
|
||||
function before_suite() {
|
||||
set -e
|
||||
$(
|
||||
rm -rf test/tmp
|
||||
mkdir -p test/tmp/dest
|
||||
mkdir -p test/tmp/src
|
||||
) >/dev/null
|
||||
|
||||
git daemon \
|
||||
--reuseaddr \
|
||||
--verbose \
|
||||
--export-all \
|
||||
--enable=receive-pack \
|
||||
--port="$SRC_GIT_DAEMON_PORT" \
|
||||
--base-path=test/tmp/src &>$SRC_GIT_DAEMON_OUTPUT &
|
||||
SRC_GIT_DAEMON_PID=$!
|
||||
|
||||
git daemon \
|
||||
--reuseaddr \
|
||||
--verbose \
|
||||
--export-all \
|
||||
--enable=receive-pack \
|
||||
--port="$DEST_GIT_DAEMON_PORT" \
|
||||
--base-path=test/tmp/dest &>$DEST_GIT_DAEMON_OUTPUT &
|
||||
DEST_GIT_DAEMON_PID=$!
|
||||
|
||||
# wait for the git daemons to start before continuing
|
||||
|
||||
if ! check_git_daemon $SRC_GIT_DAEMON_PORT; then
|
||||
echo "timeout waiting for src git daemon to start"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! check_git_daemon $DEST_GIT_DAEMON_PORT; then
|
||||
echo "timeout waiting for dest git daemon to start"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
go run test/github.go \
|
||||
-p "$DEST_API_PORT" \
|
||||
-git-daemon-url "git://localhost:$DEST_GIT_DAEMON_PORT/" &>$DEST_API_OUTPUT &
|
||||
DEST_API_PID=$!
|
||||
|
||||
script/build
|
||||
|
||||
until $(curl --output /dev/null --silent --head --fail "http://localhost:$DEST_API_PORT/ping"); do
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
set +e
|
||||
}
|
||||
|
||||
function after_suite() {
|
||||
kill "$SRC_GIT_DAEMON_PID" "$DEST_GIT_DAEMON_PID" "$DEST_API_PID"
|
||||
}
|
||||
|
||||
function setup_src() {
|
||||
rm -rf test/tmp/src
|
||||
mkdir -p test/tmp/src
|
||||
|
||||
for r in "$@"; do
|
||||
local nwo=$(echo $r | cut -d':' -f1)
|
||||
local refname=$(echo $r | cut -d':' -f2)
|
||||
local sha=$(echo $r | cut -d':' -f3)
|
||||
|
||||
local org=$(echo $nwo | cut -d'/' -f1)
|
||||
mkdir -p test/tmp/src/$org && cp -R test/fixtures/repo.git test/tmp/src/$nwo
|
||||
echo "$sha" >"test/tmp/src/$nwo/refs/$refname"
|
||||
done
|
||||
}
|
||||
|
||||
function setup_cache() {
|
||||
rm -rf test/tmp/cache
|
||||
mkdir -p test/tmp/cache
|
||||
|
||||
for r in "$@"; do
|
||||
local nwo=$(echo $r | cut -d':' -f1)
|
||||
local refname=$(echo $r | cut -d':' -f2)
|
||||
local sha=$(echo $r | cut -d':' -f3)
|
||||
mkdir -p test/tmp/cache/$nwo && cp -R test/fixtures/repo.git test/tmp/cache/$nwo/.git
|
||||
echo "$sha" >"test/tmp/cache/$nwo/.git/refs/$refname"
|
||||
done
|
||||
}
|
||||
|
||||
function setup_dest() {
|
||||
rm -rf test/tmp/dest
|
||||
mkdir -p test/tmp/dest
|
||||
|
||||
for r in "$@"; do
|
||||
local nwo=$(echo $r | cut -d':' -f1)
|
||||
local refname=$(echo $r | cut -d':' -f2)
|
||||
local sha=$(echo $r | cut -d':' -f3)
|
||||
mkdir -p test/tmp/dest/$nwo && cp -R test/fixtures/repo.git test/tmp/dest/$nwo/.git
|
||||
echo "$sha" >"test/tmp/dest/$nwo/.git/refs/$refname"
|
||||
done
|
||||
}
|
||||
|
||||
function version() {
|
||||
$ACTIONS_SYNC_BINARY version \
|
||||
&>$OUTPUT ||
|
||||
fail $1
|
||||
}
|
||||
|
||||
function pull() {
|
||||
$ACTIONS_SYNC_BINARY pull \
|
||||
--cache-dir "test/tmp/cache" \
|
||||
--source-url "git://localhost:$SRC_GIT_DAEMON_PORT" \
|
||||
"$1" "$2" \
|
||||
&>$OUTPUT ||
|
||||
fail $3
|
||||
}
|
||||
|
||||
function push() {
|
||||
$ACTIONS_SYNC_BINARY push \
|
||||
--cache-dir "test/tmp/cache" \
|
||||
--disable-push-git-auth \
|
||||
--destination-token "token" \
|
||||
--destination-url "http://localhost:$DEST_API_PORT" \
|
||||
&>$OUTPUT ||
|
||||
fail "$1"
|
||||
}
|
||||
|
||||
function push2args() {
|
||||
$ACTIONS_SYNC_BINARY push \
|
||||
--cache-dir "test/tmp/cache" \
|
||||
--disable-push-git-auth \
|
||||
--destination-token "token" \
|
||||
--destination-url "http://localhost:$DEST_API_PORT" \
|
||||
"$1" "$2" \
|
||||
&>$OUTPUT ||
|
||||
fail $3
|
||||
}
|
||||
|
||||
function push_impersonation() {
|
||||
$ACTIONS_SYNC_BINARY push \
|
||||
--cache-dir "test/tmp/cache" \
|
||||
--disable-push-git-auth \
|
||||
--destination-token "token" \
|
||||
--destination-url "http://localhost:$DEST_API_PORT" \
|
||||
--actions-admin-user $1 \
|
||||
&>$OUTPUT ||
|
||||
fail "$2"
|
||||
}
|
||||
|
||||
function sync() {
|
||||
$ACTIONS_SYNC_BINARY sync \
|
||||
--cache-dir "test/tmp/cache" \
|
||||
--source-url "git://localhost:$SRC_GIT_DAEMON_PORT" \
|
||||
--disable-push-git-auth \
|
||||
--destination-token "token" \
|
||||
--destination-url "http://localhost:$DEST_API_PORT" \
|
||||
"$1" "$2" \
|
||||
&>$OUTPUT ||
|
||||
fail $3
|
||||
}
|
||||
|
||||
function assert_cache_sha() {
|
||||
nwo=$1
|
||||
ref=$2
|
||||
expected=$3
|
||||
actual=$(cat "test/tmp/cache/$nwo/.git/refs/$ref")
|
||||
[ "$actual" == "$expected" ] || fail "unexpected cache sha \`$expected != $actual\` - \`$nwo\` \`$ref\` - \`$4\`"
|
||||
}
|
||||
|
||||
function assert_dest_sha() {
|
||||
nwo=$1
|
||||
ref=$2
|
||||
expected=$3
|
||||
actual=$(cat "test/tmp/dest/$nwo/.git/refs/$ref")
|
||||
[ "$actual" == "$expected" ] || fail "unexpected dest sha \`$expected != $actual\` - \`$nwo\` \`$ref\` - \`$4\`"
|
||||
}
|
||||
|
||||
function fail() {
|
||||
MSG=$1
|
||||
echo "FAIL: Failed $MSG"
|
||||
echo -----output-----
|
||||
cat $OUTPUT
|
||||
echo -----/output-----
|
||||
|
||||
echo -----github git daemon output-----
|
||||
cat $SRC_GIT_DAEMON_OUTPUT
|
||||
echo -----/github git daemon output-----
|
||||
|
||||
echo -----ghes git daemon output-----
|
||||
cat $DEST_GIT_DAEMON_OUTPUT
|
||||
echo -----/ghes git daemon output-----
|
||||
|
||||
echo -----ghes api output-----
|
||||
cat $DEST_API_OUTPUT
|
||||
echo -----/ghes api output-----
|
||||
exit 1
|
||||
}
|
||||
|
||||
function check_git_daemon {
|
||||
port=$1
|
||||
for i in {1..10}; do
|
||||
process=$(ps aux | grep "git daemon" | grep $port)
|
||||
if [ -z "$process" ]; then
|
||||
echo "Waiting for git daemon to start on port $port..."
|
||||
sleep 1
|
||||
else
|
||||
echo "Git daemon is running on port $port"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
echo "Git daemon did not start within the expected time."
|
||||
return 1
|
||||
}
|
||||
|
||||
test_version
|
||||
before_suite
|
||||
test_pull
|
||||
test_push
|
||||
test_sync
|
||||
+32
-29
@@ -71,11 +71,11 @@ func GetImpersonationToken(ctx context.Context, flags *PushFlags) (string, error
|
||||
|
||||
rootRequest, err := ghClient.NewRequest("GET", enterpriseAPIPath, nil)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "error constructing request for GitHub Enterprise client.")
|
||||
return "", errors.Wrap(err, "error constructing request for GitHub Enterprise client")
|
||||
}
|
||||
rootResponse, err := ghClient.Do(ctx, rootRequest, nil)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "error checking connectivity for GitHub Enterprise client.")
|
||||
return "", errors.Wrap(err, "error checking connectivity for GitHub Enterprise client")
|
||||
}
|
||||
|
||||
scopesHeader := rootResponse.Header.Get(xOAuthScopesHeader)
|
||||
@@ -96,7 +96,7 @@ func GetImpersonationToken(ctx context.Context, flags *PushFlags) (string, error
|
||||
|
||||
impersonationToken, _, err := ghClient.Admin.CreateUserImpersonation(ctx, flags.ActionsAdminUser, &github.ImpersonateUserOptions{Scopes: []string{minimumRepositoryScope, "workflow"}})
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "failed to impersonate Actions admin user.")
|
||||
return "", errors.Wrap(err, "failed to impersonate Actions admin user")
|
||||
}
|
||||
|
||||
fmt.Printf("got the impersonation token for `%s` ...\n", flags.ActionsAdminUser)
|
||||
@@ -205,38 +205,41 @@ func getOrCreateGitHubRepo(ctx context.Context, client *github.Client, repoName,
|
||||
}
|
||||
|
||||
// check if repository already exists
|
||||
ghRepo, resp, err := client.Repositories.Get(ctx, ownerName, repoName)
|
||||
|
||||
if err == nil {
|
||||
fmt.Printf("Existing repo `%s/%s`\n", ownerName, repoName)
|
||||
} else if resp != nil && resp.StatusCode == 404 {
|
||||
var ghRepo *github.Repository
|
||||
var resp *github.Response
|
||||
ghRepo, resp, err = client.Repositories.Get(ctx, ownerName, repoName)
|
||||
if err != nil {
|
||||
// repo not existing yet - try to create
|
||||
visibility := github.String("public")
|
||||
if isAE {
|
||||
visibility = github.String("internal")
|
||||
}
|
||||
repo := &github.Repository{
|
||||
Name: github.String(repoName),
|
||||
HasIssues: github.Bool(false),
|
||||
HasWiki: github.Bool(false),
|
||||
HasPages: github.Bool(false),
|
||||
HasProjects: github.Bool(false),
|
||||
Visibility: visibility,
|
||||
if resp != nil && resp.StatusCode == 404 {
|
||||
fmt.Printf("repo `%s/%s` doesn't exist, attempting to create\n", ownerName, repoName)
|
||||
|
||||
visibility := github.String("public")
|
||||
if isAE {
|
||||
visibility = github.String("internal")
|
||||
}
|
||||
|
||||
repo := &github.Repository{
|
||||
Name: github.String(repoName),
|
||||
HasIssues: github.Bool(false),
|
||||
HasWiki: github.Bool(false),
|
||||
HasPages: github.Bool(false),
|
||||
HasProjects: github.Bool(false),
|
||||
Visibility: visibility,
|
||||
}
|
||||
|
||||
ghRepo, _, err = client.Repositories.Create(ctx, createRepoOrgName, repo)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error creating repository %s/%s", ownerName, repoName)
|
||||
}
|
||||
|
||||
fmt.Printf("created repo `%s/%s`\n", ownerName, repoName)
|
||||
return ghRepo, nil
|
||||
}
|
||||
|
||||
ghRepo, _, err = client.Repositories.Create(ctx, createRepoOrgName, repo)
|
||||
if err == nil {
|
||||
fmt.Printf("Created repo `%s/%s`\n", ownerName, repoName)
|
||||
} else {
|
||||
return nil, errors.Wrapf(err, "error creating repository %s/%s", ownerName, repoName)
|
||||
}
|
||||
} else if err != nil {
|
||||
return nil, errors.Wrapf(err, "error creating repository %s/%s", ownerName, repoName)
|
||||
}
|
||||
|
||||
if ghRepo == nil {
|
||||
return nil, errors.New("error repository is nil")
|
||||
}
|
||||
fmt.Printf("found existing repo `%s/%s`\n", ownerName, repoName)
|
||||
return ghRepo, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ func Test_extractSourceDest(t *testing.T) {
|
||||
assert.Equal(t, "src_owner/src_repo", src)
|
||||
assert.Equal(t, "dst_owner/dst_repo", dst)
|
||||
|
||||
src, dst, err = extractSourceDest("src_owner/src_repo:dst_owner/dst_repo:bogus/bogus")
|
||||
_, _, err = extractSourceDest("src_owner/src_repo:dst_owner/dst_repo:bogus/bogus")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -37,24 +37,24 @@ func Test_validateNwo(t *testing.T) {
|
||||
assert.Equal(t, "a/b", nwo)
|
||||
|
||||
// no slash separator
|
||||
nwo, err = validateNwo("bogus")
|
||||
_, err = validateNwo("bogus")
|
||||
require.Error(t, err)
|
||||
|
||||
// no owner
|
||||
nwo, err = validateNwo("/bogus")
|
||||
_, err = validateNwo("/bogus")
|
||||
require.Error(t, err)
|
||||
|
||||
// no repo name
|
||||
nwo, err = validateNwo("bogus/")
|
||||
_, err = validateNwo("bogus/")
|
||||
require.Error(t, err)
|
||||
|
||||
nwo, err = validateNwo("bogus whitespace/bogus")
|
||||
_, err = validateNwo("bogus whitespace/bogus")
|
||||
require.Error(t, err)
|
||||
|
||||
nwo, err = validateNwo("bogus/bogus/bogus")
|
||||
_, err = validateNwo("bogus/bogus/bogus")
|
||||
require.Error(t, err)
|
||||
|
||||
// A separate destination is only permitted for "repo names", not NWOs.
|
||||
nwo, err = validateNwo("owner/repo:bogus/bogus")
|
||||
_, err = validateNwo("owner/repo:bogus/bogus")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user