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 }}
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
days-before-issue-stale: 30
|
||||
days-before-issue-close: 14
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
- run: go mod vendor
|
||||
|
||||
# Ruby is required for licensed
|
||||
- uses: ruby/setup-ruby@6bd3d993c602f6b675728ebaecb2b569ff86e99b
|
||||
- uses: ruby/setup-ruby@5f19ec79cedfadb78ab837f95b87734d0003c899
|
||||
with:
|
||||
ruby-version: "3.2"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-3
@@ -1,5 +1,4 @@
|
||||
project_name: actions/actions-sync
|
||||
|
||||
builds:
|
||||
- id: build
|
||||
goos:
|
||||
@@ -20,7 +19,6 @@ release:
|
||||
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
|
||||
# To test, go to the Actions tab and run the "Actions Sync E2E Sanity Test" workflow
|
||||
draft: true
|
||||
|
||||
|
||||
|
||||
@@ -14,24 +14,6 @@ It is designed to work when:
|
||||
* The GitHub Enterprise instance is separate from the rest of the internet.
|
||||
* The GitHub Enterprise instance is connected to the rest of the internet.
|
||||
|
||||
### Note
|
||||
|
||||
Thank you for your interest in this GitHub action, however, right now we are not taking contributions. Add commentMore actionsAdd commentMore actions
|
||||
|
||||
We continue to focus our resources on strategic areas that help our customers be successful while making developers' lives easier. While GitHub Actions remains a key part of this vision, we are allocating resources towards other areas of Actions and are not taking contributions to this repository at this time. The GitHub public roadmap is the best place to follow along for any updates on features we’re working on and what stage they’re in.
|
||||
|
||||
We are taking the following steps to better direct requests related to GitHub Actions, including:
|
||||
|
||||
1. We will be directing questions and support requests to our [Community Discussions area](https://github.com/orgs/community/discussions/categories/actions)
|
||||
|
||||
2. High Priority bugs can be reported through Community Discussions or you can report these to our support team https://support.github.com/contact/bug-report.
|
||||
|
||||
3. Security Issues should be handled as per our [security.md](security.md)
|
||||
|
||||
We will still provide security updates for this project and fix major breaking changes during this time.
|
||||
|
||||
You are welcome to still raise bugs in this repo.
|
||||
|
||||
## Connected instances
|
||||
|
||||
When there are machines which have access to both the public internet and the GHES instance run `actions-sync sync`.
|
||||
@@ -128,3 +110,7 @@ When no machine has access to both the public internet and the GHES instance:
|
||||
|
||||
When creating a personal access token include the `repo` and `workflow` scopes. Include the `site_admin` scope (optional) if you want organizations to be created as necessary or you want to use the impersonation logic for the `push` or `sync` commands.
|
||||
|
||||
## Contributing
|
||||
|
||||
If you would like to contribute your work back to the project, please see
|
||||
[`CONTRIBUTING.md`](CONTRIBUTING.md).
|
||||
|
||||
+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
|
||||
}
|
||||
|
||||
CGO_ENABLED=0 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