mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 01:28:45 +01:00
Signed-off-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com> Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: reggie-k <regina.voloshin@codefresh.io> Signed-off-by: shubham singh mahar <shubhammahar1306@gmail.com> Signed-off-by: CI <ci@argoproj.com> Signed-off-by: Josh Soref <jsoref@gmail.com> Signed-off-by: renovate[bot] <renovate[bot]@users.noreply.github.com> Signed-off-by: Jakub Rudnik <jakub@rudnik.io> Signed-off-by: ioleksiuk <ioleksiuk@users.noreply.github.com> Signed-off-by: Illia Oleksiuk <ilya.oleksiuk@gmail.com> Signed-off-by: Aya <ayia.hosni@gmail.com> Co-authored-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Pasha Kostohrys <pasha.kostohrys@gmail.com> Co-authored-by: pasha <pasha.k@fyxt.com> Co-authored-by: Regina Voloshin <regina.voloshin@codefresh.io> Co-authored-by: Shubham Singh <shubhammahar1306@gmail.com> Co-authored-by: shubham singh mahar <smahar@obmondo.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: CI <ci@argoproj.com> Co-authored-by: Josh Soref <2119212+jsoref@users.noreply.github.com> Co-authored-by: argoproj-renovate[bot] <161757507+argoproj-renovate[bot]@users.noreply.github.com> Co-authored-by: Jakub Rudnik <jakub@rudnik.io> Co-authored-by: Illia Oleksiuk <42911468+ioleksiuk@users.noreply.github.com> Co-authored-by: Aya Hosni <ayia.hosni@gmail.com> Co-authored-by: Nitish Kumar <justnitish06@gmail.com>
This commit is contained in:
11
.github/workflows/ci-build.yaml
vendored
11
.github/workflows/ci-build.yaml
vendored
@@ -194,7 +194,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- name: Create symlink in GOPATH
|
||||
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
|
||||
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
||||
with:
|
||||
@@ -271,13 +271,13 @@ jobs:
|
||||
# We need to vendor go modules for codegen yet
|
||||
go mod download
|
||||
go mod vendor -v
|
||||
# generalizing repo name for forks: ${{ github.event.repository.name }}
|
||||
working-directory: /home/runner/go/src/github.com/argoproj/${{ github.event.repository.name }}
|
||||
# generalizing repo name for forks: ${{ github.event.repository.name }}
|
||||
working-directory: /home/runner/go/src/github.com/argoproj/${{ github.event.repository.name }}
|
||||
- name: Install toolchain for codegen
|
||||
run: |
|
||||
make install-codegen-tools-local
|
||||
make install-go-tools-local
|
||||
# generalizing repo name for forks: ${{ github.event.repository.name }}
|
||||
# generalizing repo name for forks: ${{ github.event.repository.name }}
|
||||
working-directory: /home/runner/go/src/github.com/argoproj/${{ github.event.repository.name }}
|
||||
# We install kustomize in the dist directory
|
||||
- name: Add dist to PATH
|
||||
@@ -431,9 +431,6 @@ jobs:
|
||||
- changes
|
||||
env:
|
||||
ARGOCD_FAKE_IN_CLUSTER: 'true'
|
||||
ARGOCD_SSH_DATA_PATH: '/tmp/argo-e2e/app/config/ssh'
|
||||
ARGOCD_TLS_DATA_PATH: '/tmp/argo-e2e/app/config/tls'
|
||||
ARGOCD_E2E_SSH_KNOWN_HOSTS: '../fixture/certs/ssh_known_hosts'
|
||||
ARGOCD_E2E_K3S: 'true'
|
||||
ARGOCD_IN_CI: 'true'
|
||||
ARGOCD_E2E_APISERVER_PORT: '8088'
|
||||
|
||||
27
Makefile
27
Makefile
@@ -76,8 +76,10 @@ ARGOCD_E2E_REDIS_PORT?=6379
|
||||
ARGOCD_E2E_DEX_PORT?=5556
|
||||
ARGOCD_E2E_YARN_HOST?=localhost
|
||||
ARGOCD_E2E_DISABLE_AUTH?=
|
||||
ARGOCD_E2E_DIR?=/tmp/argo-e2e
|
||||
|
||||
ARGOCD_E2E_TEST_TIMEOUT?=90m
|
||||
ARGOCD_E2E_RERUN_FAILS?=5
|
||||
|
||||
ARGOCD_IN_CI?=false
|
||||
ARGOCD_TEST_E2E?=true
|
||||
@@ -461,7 +463,7 @@ test-e2e:
|
||||
test-e2e-local: cli-local
|
||||
# NO_PROXY ensures all tests don't go out through a proxy if one is configured on the test system
|
||||
export GO111MODULE=off
|
||||
DIST_DIR=${DIST_DIR} RERUN_FAILS=5 PACKAGES="./test/e2e" ARGOCD_E2E_RECORD=${ARGOCD_E2E_RECORD} ARGOCD_CONFIG_DIR=$(HOME)/.config/argocd-e2e ARGOCD_GPG_ENABLED=true NO_PROXY=* ./hack/test.sh -timeout $(ARGOCD_E2E_TEST_TIMEOUT) -v -args -test.gocoverdir="$(PWD)/test-results"
|
||||
DIST_DIR=${DIST_DIR} RERUN_FAILS=$(ARGOCD_E2E_RERUN_FAILS) PACKAGES="./test/e2e" ARGOCD_E2E_RECORD=${ARGOCD_E2E_RECORD} ARGOCD_CONFIG_DIR=$(HOME)/.config/argocd-e2e ARGOCD_GPG_ENABLED=true NO_PROXY=* ./hack/test.sh -timeout $(ARGOCD_E2E_TEST_TIMEOUT) -v -args -test.gocoverdir="$(PWD)/test-results"
|
||||
|
||||
# Spawns a shell in the test server container for debugging purposes
|
||||
debug-test-server: test-tools-image
|
||||
@@ -485,13 +487,13 @@ start-e2e-local: mod-vendor-local dep-ui-local cli-local
|
||||
kubectl create ns argocd-e2e-external || true
|
||||
kubectl create ns argocd-e2e-external-2 || true
|
||||
kubectl config set-context --current --namespace=argocd-e2e
|
||||
kustomize build test/manifests/base | kubectl apply --server-side -f -
|
||||
kustomize build test/manifests/base | kubectl apply --server-side --force-conflicts -f -
|
||||
kubectl apply -f https://raw.githubusercontent.com/open-cluster-management/api/a6845f2ebcb186ec26b832f60c988537a58f3859/cluster/v1alpha1/0000_04_clusters.open-cluster-management.io_placementdecisions.crd.yaml
|
||||
# Create GPG keys and source directories
|
||||
if test -d /tmp/argo-e2e/app/config/gpg; then rm -rf /tmp/argo-e2e/app/config/gpg/*; fi
|
||||
mkdir -p /tmp/argo-e2e/app/config/gpg/keys && chmod 0700 /tmp/argo-e2e/app/config/gpg/keys
|
||||
mkdir -p /tmp/argo-e2e/app/config/gpg/source && chmod 0700 /tmp/argo-e2e/app/config/gpg/source
|
||||
mkdir -p /tmp/argo-e2e/app/config/plugin && chmod 0700 /tmp/argo-e2e/app/config/plugin
|
||||
if test -d $(ARGOCD_E2E_DIR)/app/config/gpg; then rm -rf $(ARGOCD_E2E_DIR)/app/config/gpg/*; fi
|
||||
mkdir -p $(ARGOCD_E2E_DIR)/app/config/gpg/keys && chmod 0700 $(ARGOCD_E2E_DIR)/app/config/gpg/keys
|
||||
mkdir -p $(ARGOCD_E2E_DIR)/app/config/gpg/source && chmod 0700 $(ARGOCD_E2E_DIR)/app/config/gpg/source
|
||||
mkdir -p $(ARGOCD_E2E_DIR)/app/config/plugin && chmod 0700 $(ARGOCD_E2E_DIR)/app/config/plugin
|
||||
# create folders to hold go coverage results for each component
|
||||
mkdir -p /tmp/coverage/app-controller
|
||||
mkdir -p /tmp/coverage/api-server
|
||||
@@ -500,13 +502,14 @@ start-e2e-local: mod-vendor-local dep-ui-local cli-local
|
||||
mkdir -p /tmp/coverage/notification
|
||||
mkdir -p /tmp/coverage/commit-server
|
||||
# set paths for locally managed ssh known hosts and tls certs data
|
||||
ARGOCD_SSH_DATA_PATH=/tmp/argo-e2e/app/config/ssh \
|
||||
ARGOCD_TLS_DATA_PATH=/tmp/argo-e2e/app/config/tls \
|
||||
ARGOCD_GPG_DATA_PATH=/tmp/argo-e2e/app/config/gpg/source \
|
||||
ARGOCD_GNUPGHOME=/tmp/argo-e2e/app/config/gpg/keys \
|
||||
ARGOCD_E2E_DIR=$(ARGOCD_E2E_DIR) \
|
||||
ARGOCD_SSH_DATA_PATH=$(ARGOCD_E2E_DIR)/app/config/ssh \
|
||||
ARGOCD_TLS_DATA_PATH=$(ARGOCD_E2E_DIR)/app/config/tls \
|
||||
ARGOCD_GPG_DATA_PATH=$(ARGOCD_E2E_DIR)/app/config/gpg/source \
|
||||
ARGOCD_GNUPGHOME=$(ARGOCD_E2E_DIR)/app/config/gpg/keys \
|
||||
ARGOCD_GPG_ENABLED=$(ARGOCD_GPG_ENABLED) \
|
||||
ARGOCD_PLUGINCONFIGFILEPATH=/tmp/argo-e2e/app/config/plugin \
|
||||
ARGOCD_PLUGINSOCKFILEPATH=/tmp/argo-e2e/app/config/plugin \
|
||||
ARGOCD_PLUGINCONFIGFILEPATH=$(ARGOCD_E2E_DIR)/app/config/plugin \
|
||||
ARGOCD_PLUGINSOCKFILEPATH=$(ARGOCD_E2E_DIR)/app/config/plugin \
|
||||
ARGOCD_GIT_CONFIG=$(PWD)/test/e2e/fixture/gitconfig \
|
||||
ARGOCD_E2E_DISABLE_AUTH=false \
|
||||
ARGOCD_ZJWT_FEATURE_FLAG=always \
|
||||
|
||||
@@ -3,29 +3,33 @@
|
||||
The test [directory](https://github.com/argoproj/argo-cd/tree/master/test) contains E2E tests and test applications. The tests assume that Argo CD services are installed into `argocd-e2e` namespace or cluster in current context. A throw-away
|
||||
namespace `argocd-e2e***` is created prior to the execution of the tests. The throw-away namespace is used as a target namespace for test applications.
|
||||
|
||||
The [/test/e2e/testdata](https://github.com/argoproj/argo-cd/tree/master/test/e2e/testdata) directory contains various Argo CD applications. Before test execution, the directory is copied into `/tmp/argo-e2e***` temp directory and used in tests as a
|
||||
The [/test/e2e/testdata](https://github.com/argoproj/argo-cd/tree/master/test/e2e/testdata) directory contains various Argo CD applications. Before test execution, the directory is copied into `/tmp/argo-e2e***` temp directory (configurable by `ARGOCD_E2E_DIR`) and used in tests as a
|
||||
Git repository via file url: `file:///tmp/argo-e2e***`.
|
||||
|
||||
> [!NOTE]
|
||||
> You might get an error such as `unable to ls-remote HEAD on repository: failed to list refs: repository not found` when querying the local repository exposed through the e2e server running in a container.
|
||||
> This is often caused by `/tmp` directoring sharing protection. You can configure a different directory with `ARGOCD_E2E_DIR`, or disable the directory sharing protection.
|
||||
>
|
||||
> **Rancher Desktop Volume Sharing**
|
||||
>
|
||||
> The e2e git server runs in a container. If you are using Rancher Desktop, you will need to enable volume sharing for
|
||||
> the e2e container to access the testdata directory. To do this, add the following to
|
||||
> To do enable `/tmp` sharing, add the following to
|
||||
> `~/Library/Application\ Support/rancher-desktop/lima/_config/override.yaml` and restart Rancher Desktop:
|
||||
>
|
||||
> ```yaml
|
||||
> mounts:
|
||||
> - location: /private/tmp
|
||||
> writable: true
|
||||
> - location: /private/tmp
|
||||
> writable: true
|
||||
> ```
|
||||
|
||||
## Running Tests Locally
|
||||
|
||||
### With virtualized chain
|
||||
|
||||
1. Start the e2e version `make start-e2e`
|
||||
2. Run the tests: `make test-e2e`
|
||||
|
||||
### With local chain
|
||||
|
||||
1. Start the e2e version `make start-e2e-local`
|
||||
2. Run the tests: `make test-e2e-local`
|
||||
|
||||
@@ -37,32 +41,32 @@ You can observe the tests by using the UI [http://localhost:4000/applications](h
|
||||
|
||||
The Makefile's `start-e2e` target starts instances of ArgoCD on your local machine, of which the most will require a network listener. If, for any reason, your machine already has network services listening on the same ports, then the e2e tests will not run. You can derive from the defaults by setting the following environment variables before you run `make start-e2e`:
|
||||
|
||||
* `ARGOCD_E2E_APISERVER_PORT`: Listener port for `argocd-server` (default: `8080`)
|
||||
* `ARGOCD_E2E_REPOSERVER_PORT`: Listener port for `argocd-reposerver` (default: `8081`)
|
||||
* `ARGOCD_E2E_DEX_PORT`: Listener port for `dex` (default: `5556`)
|
||||
* `ARGOCD_E2E_REDIS_PORT`: Listener port for `redis` (default: `6379`)
|
||||
* `ARGOCD_E2E_YARN_CMD`: Command to use for starting the UI via Yarn (default: `yarn`)
|
||||
- `ARGOCD_E2E_APISERVER_PORT`: Listener port for `argocd-server` (default: `8080`)
|
||||
- `ARGOCD_E2E_REPOSERVER_PORT`: Listener port for `argocd-reposerver` (default: `8081`)
|
||||
- `ARGOCD_E2E_DEX_PORT`: Listener port for `dex` (default: `5556`)
|
||||
- `ARGOCD_E2E_REDIS_PORT`: Listener port for `redis` (default: `6379`)
|
||||
- `ARGOCD_E2E_YARN_CMD`: Command to use for starting the UI via Yarn (default: `yarn`)
|
||||
- `ARGOCD_E2E_DIR`: Local path to the repository to use for ephemeral test data
|
||||
|
||||
If you have changed the port for `argocd-server`, be sure to also set `ARGOCD_SERVER` environment variable to point to that port, e.g. `export ARGOCD_SERVER=localhost:8888` before running `make test-e2e` so that the test will communicate to the correct server component.
|
||||
|
||||
|
||||
## Test Isolation
|
||||
|
||||
Some effort has been made to balance test isolation with speed. Tests are isolated as follows as each test gets:
|
||||
|
||||
* A random 5 character ID.
|
||||
* A unique Git repository containing the `testdata` in `/tmp/argo-e2e/${id}`.
|
||||
* A namespace `argocd-e2e-ns-${id}`.
|
||||
* A primary name for the app `argocd-e2e-${id}`.
|
||||
- A random 5 character ID.
|
||||
- A unique Git repository containing the `testdata` in `/tmp/argo-e2e/${id}`.
|
||||
- A namespace `argocd-e2e-ns-${id}`.
|
||||
- A primary name for the app `argocd-e2e-${id}`.
|
||||
|
||||
## Run only a subset of tests
|
||||
|
||||
Running all tests locally is a time-consuming process. To run only a subset of tests, you can set the `TEST_MODULE` environment variable.
|
||||
For example, to run only the OCI tests, you can set the variable as follows: `make TEST_MODULE=./test/e2e/oci_test.go test-e2e-local`
|
||||
Running all tests locally is a time-consuming process. To run only a subset of tests, you can set the `TEST_MODULE` environment variable.
|
||||
For example, to run only the OCI tests, you can set the variable as follows: `make TEST_MODULE=./test/e2e/oci_test.go test-e2e-local`
|
||||
|
||||
If you want to get a more fine-grained control over which tests to run, you can also try `make TEST_FLAGS="-run <TEST_METHOD_NAME_REGEXP>" test-e2e-local`
|
||||
For individual tests you can run them using the IDE run test feature
|
||||
|
||||
For individual tests you can run them using the IDE run test feature
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Tests fails to delete `argocd-e2e-ns-*` namespaces.**
|
||||
|
||||
@@ -26,7 +26,7 @@ func (c *Context) RunningCMPServer(configFile string) *Context {
|
||||
// It blocks until the socket file is created or times out after 10 seconds.
|
||||
func startCMPServer(t *testing.T, configDir string) {
|
||||
t.Helper()
|
||||
pluginSockFilePath := path.Join(fixture.TmpDir, fixture.PluginSockFilePath)
|
||||
pluginSockFilePath := path.Join(fixture.TmpDir(), fixture.PluginSockFilePath)
|
||||
t.Setenv("ARGOCD_BINARY_NAME", "argocd-cmp-server")
|
||||
// ARGOCD_PLUGINSOCKFILEPATH should be set as the same value as repo server env var
|
||||
t.Setenv("ARGOCD_PLUGINSOCKFILEPATH", pluginSockFilePath)
|
||||
|
||||
@@ -23,6 +23,10 @@ type Context struct {
|
||||
|
||||
func Given(t *testing.T) *Context {
|
||||
t.Helper()
|
||||
|
||||
fixture.EnsureCleanState(t)
|
||||
|
||||
// TODO: Appset EnsureCleanState specific logic should be moved to the main EnsureCleanState function (https://github.com/argoproj/argo-cd/issues/24307)
|
||||
utils.EnsureCleanState(t)
|
||||
return &Context{t: t}
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
argoexec "github.com/argoproj/argo-cd/v3/util/exec"
|
||||
)
|
||||
|
||||
func Run(workDir, name string, args ...string) (string, error) {
|
||||
return RunWithStdin("", workDir, name, args...)
|
||||
}
|
||||
|
||||
func RunWithStdin(stdin, workDir, name string, args ...string) (string, error) {
|
||||
cmd := exec.CommandContext(context.Background(), name, args...)
|
||||
if stdin != "" {
|
||||
cmd.Stdin = strings.NewReader(stdin)
|
||||
}
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Dir = workDir
|
||||
|
||||
return argoexec.RunCommandExt(cmd, argoexec.CmdOpts{})
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import (
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned"
|
||||
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
|
||||
"github.com/argoproj/argo-cd/v3/util/errors"
|
||||
)
|
||||
|
||||
type ExternalNamespace string
|
||||
@@ -49,7 +48,6 @@ const (
|
||||
// Note: this is NOT the namespace the ApplicationSet controller is deployed to; see ArgoCDNamespace.
|
||||
ApplicationsResourcesNamespace = "applicationset-e2e"
|
||||
|
||||
TmpDir = "/tmp/applicationset-e2e"
|
||||
TestingLabel = "e2e.argoproj.io"
|
||||
)
|
||||
|
||||
@@ -209,12 +207,6 @@ func EnsureCleanState(t *testing.T) {
|
||||
|
||||
require.NoError(t, waitForExpectedClusterState(t))
|
||||
|
||||
// remove tmp dir
|
||||
require.NoError(t, os.RemoveAll(TmpDir))
|
||||
|
||||
// create tmp dir
|
||||
errors.NewHandler(t).FailOnErr(Run("", "mkdir", "-p", TmpDir))
|
||||
|
||||
// We can switch user and as result in previous state we will have non-admin user, this case should be reset
|
||||
require.NoError(t, fixture.LoginAs("admin"))
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ func AddCustomCACert(t *testing.T) {
|
||||
errors.NewHandler(t).FailOnErr(fixture.RunCli(args...))
|
||||
certData, err := os.ReadFile(caCertPath)
|
||||
require.NoError(t, err)
|
||||
err = os.WriteFile(fixture.TmpDir+"/app/config/tls/localhost", certData, 0o644)
|
||||
err = os.WriteFile(fixture.TmpDir()+"/app/config/tls/localhost", certData, 0o644)
|
||||
require.NoError(t, err)
|
||||
err = os.WriteFile(fixture.TmpDir+"/app/config/tls/127.0.0.1", certData, 0o644)
|
||||
err = os.WriteFile(fixture.TmpDir()+"/app/config/tls/127.0.0.1", certData, 0o644)
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
args := []string{"cert", "add-tls", "argocd-e2e-server", "--upsert", "--from", caCertPath}
|
||||
@@ -58,7 +58,7 @@ func AddCustomSSHKnownHostsKeys(t *testing.T) {
|
||||
if fixture.IsLocal() {
|
||||
knownHostsData, err := os.ReadFile(knownHostsPath)
|
||||
require.NoError(t, err)
|
||||
err = os.WriteFile(fixture.TmpDir+"/app/config/ssh/ssh_known_hosts", knownHostsData, 0o644)
|
||||
err = os.WriteFile(fixture.TmpDir()+"/app/config/ssh/ssh_known_hosts", knownHostsData, 0o644)
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
fixture.RestartAPIServer(t)
|
||||
|
||||
@@ -53,7 +53,8 @@ const (
|
||||
defaultNotificationServer = "localhost:9001"
|
||||
|
||||
// ensure all repos are in one directory tree, so we can easily clean them up
|
||||
TmpDir = "/tmp/argo-e2e"
|
||||
// TmpDir can be overridden via ARGOCD_E2E_DIR environment variable
|
||||
defaultTmpDir = "/tmp/argo-e2e"
|
||||
repoDir = "testdata.git"
|
||||
submoduleDir = "submodule.git"
|
||||
submoduleParentDir = "submoduleParent.git"
|
||||
@@ -149,6 +150,12 @@ func AppNamespace() string {
|
||||
return GetEnvWithDefault("ARGOCD_E2E_APP_NAMESPACE", ArgoCDAppNamespace)
|
||||
}
|
||||
|
||||
// TmpDir returns the base directory for e2e test data.
|
||||
// It can be overridden via the ARGOCD_E2E_DIR environment variable.
|
||||
func TmpDir() string {
|
||||
return GetEnvWithDefault("ARGOCD_E2E_DIR", defaultTmpDir)
|
||||
}
|
||||
|
||||
// getKubeConfig creates new kubernetes client config using specified config path and config overrides variables
|
||||
func getKubeConfig(configPath string, overrides clientcmd.ConfigOverrides) *rest.Config {
|
||||
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
|
||||
@@ -300,15 +307,15 @@ func ShortId() string {
|
||||
}
|
||||
|
||||
func repoDirectory() string {
|
||||
return path.Join(TmpDir, repoDir)
|
||||
return path.Join(TmpDir(), repoDir)
|
||||
}
|
||||
|
||||
func submoduleDirectory() string {
|
||||
return path.Join(TmpDir, submoduleDir)
|
||||
return path.Join(TmpDir(), submoduleDir)
|
||||
}
|
||||
|
||||
func submoduleParentDirectory() string {
|
||||
return path.Join(TmpDir, submoduleParentDir)
|
||||
return path.Join(TmpDir(), submoduleParentDir)
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -325,16 +332,18 @@ const (
|
||||
)
|
||||
|
||||
func RepoURL(urlType RepoURLType) string {
|
||||
// SSH URLs use the container path (defaultTmpDir) because sshd runs inside Docker
|
||||
// where $ARGOCD_E2E_DIR is mounted to /tmp/argo-e2e
|
||||
switch urlType {
|
||||
// Git server via SSH
|
||||
case RepoURLTypeSSH:
|
||||
return GetEnvWithDefault(EnvRepoURLTypeSSH, "ssh://root@localhost:2222/tmp/argo-e2e/testdata.git")
|
||||
return GetEnvWithDefault(EnvRepoURLTypeSSH, "ssh://root@localhost:2222"+defaultTmpDir+"/testdata.git")
|
||||
// Git submodule repo
|
||||
case RepoURLTypeSSHSubmodule:
|
||||
return GetEnvWithDefault(EnvRepoURLTypeSSHSubmodule, "ssh://root@localhost:2222/tmp/argo-e2e/submodule.git")
|
||||
return GetEnvWithDefault(EnvRepoURLTypeSSHSubmodule, "ssh://root@localhost:2222"+defaultTmpDir+"/submodule.git")
|
||||
// Git submodule parent repo
|
||||
case RepoURLTypeSSHSubmoduleParent:
|
||||
return GetEnvWithDefault(EnvRepoURLTypeSSHSubmoduleParent, "ssh://root@localhost:2222/tmp/argo-e2e/submoduleParent.git")
|
||||
return GetEnvWithDefault(EnvRepoURLTypeSSHSubmoduleParent, "ssh://root@localhost:2222"+defaultTmpDir+"/submoduleParent.git")
|
||||
// Git server via HTTPS
|
||||
case RepoURLTypeHTTPS:
|
||||
return GetEnvWithDefault(EnvRepoURLTypeHTTPS, "https://localhost:9443/argo-e2e/testdata.git")
|
||||
@@ -898,38 +907,39 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) {
|
||||
return err
|
||||
},
|
||||
func() error {
|
||||
err := os.RemoveAll(TmpDir)
|
||||
tmpDir := TmpDir()
|
||||
err := os.RemoveAll(tmpDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = Run("", "mkdir", "-p", TmpDir)
|
||||
_, err = Run("", "mkdir", "-p", tmpDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create TLS and SSH certificate directories
|
||||
if IsLocal() {
|
||||
_, err = Run("", "mkdir", "-p", TmpDir+"/app/config/tls")
|
||||
_, err = Run("", "mkdir", "-p", tmpDir+"/app/config/tls")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = Run("", "mkdir", "-p", TmpDir+"/app/config/ssh")
|
||||
_, err = Run("", "mkdir", "-p", tmpDir+"/app/config/ssh")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// For signing during the tests
|
||||
_, err = Run("", "mkdir", "-p", TmpDir+"/gpg")
|
||||
_, err = Run("", "mkdir", "-p", tmpDir+"/gpg")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = Run("", "chmod", "0700", TmpDir+"/gpg")
|
||||
_, err = Run("", "chmod", "0700", tmpDir+"/gpg")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prevGnuPGHome := os.Getenv("GNUPGHOME")
|
||||
t.Setenv("GNUPGHOME", TmpDir+"/gpg")
|
||||
t.Setenv("GNUPGHOME", tmpDir+"/gpg")
|
||||
//nolint:errcheck
|
||||
Run("", "pkill", "-9", "gpg-agent")
|
||||
_, err = Run("", "gpg", "--import", "../fixture/gpg/signingkey.asc")
|
||||
@@ -940,23 +950,23 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) {
|
||||
|
||||
// recreate GPG directories
|
||||
if IsLocal() {
|
||||
_, err = Run("", "mkdir", "-p", TmpDir+"/app/config/gpg/source")
|
||||
_, err = Run("", "mkdir", "-p", tmpDir+"/app/config/gpg/source")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = Run("", "mkdir", "-p", TmpDir+"/app/config/gpg/keys")
|
||||
_, err = Run("", "mkdir", "-p", tmpDir+"/app/config/gpg/keys")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = Run("", "chmod", "0700", TmpDir+"/app/config/gpg/keys")
|
||||
_, err = Run("", "chmod", "0700", tmpDir+"/app/config/gpg/keys")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = Run("", "mkdir", "-p", TmpDir+PluginSockFilePath)
|
||||
_, err = Run("", "mkdir", "-p", tmpDir+PluginSockFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = Run("", "chmod", "0700", TmpDir+PluginSockFilePath)
|
||||
_, err = Run("", "chmod", "0700", tmpDir+PluginSockFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1158,7 +1168,7 @@ func AddSignedFile(t *testing.T, path, contents string) {
|
||||
WriteFile(t, path, contents)
|
||||
|
||||
prevGnuPGHome := os.Getenv("GNUPGHOME")
|
||||
t.Setenv("GNUPGHOME", TmpDir+"/gpg")
|
||||
t.Setenv("GNUPGHOME", TmpDir()+"/gpg")
|
||||
errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "diff"))
|
||||
errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "add", "."))
|
||||
errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "-c", "user.signingkey="+GpgGoodKeyID, "commit", "-S", "-am", "add file"))
|
||||
@@ -1171,7 +1181,7 @@ func AddSignedFile(t *testing.T, path, contents string) {
|
||||
func AddSignedTag(t *testing.T, name string) {
|
||||
t.Helper()
|
||||
prevGnuPGHome := os.Getenv("GNUPGHOME")
|
||||
t.Setenv("GNUPGHOME", TmpDir+"/gpg")
|
||||
t.Setenv("GNUPGHOME", TmpDir()+"/gpg")
|
||||
defer t.Setenv("GNUPGHOME", prevGnuPGHome)
|
||||
errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "-c", "user.signingkey="+GpgGoodKeyID, "tag", "-sm", "add signed tag", name))
|
||||
if IsRemote() {
|
||||
@@ -1182,7 +1192,7 @@ func AddSignedTag(t *testing.T, name string) {
|
||||
func AddTag(t *testing.T, name string) {
|
||||
t.Helper()
|
||||
prevGnuPGHome := os.Getenv("GNUPGHOME")
|
||||
t.Setenv("GNUPGHOME", TmpDir+"/gpg")
|
||||
t.Setenv("GNUPGHOME", TmpDir()+"/gpg")
|
||||
defer t.Setenv("GNUPGHOME", prevGnuPGHome)
|
||||
errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "tag", name))
|
||||
if IsRemote() {
|
||||
@@ -1193,7 +1203,7 @@ func AddTag(t *testing.T, name string) {
|
||||
func AddTagWithForce(t *testing.T, name string) {
|
||||
t.Helper()
|
||||
prevGnuPGHome := os.Getenv("GNUPGHOME")
|
||||
t.Setenv("GNUPGHOME", TmpDir+"/gpg")
|
||||
t.Setenv("GNUPGHOME", TmpDir()+"/gpg")
|
||||
defer t.Setenv("GNUPGHOME", prevGnuPGHome)
|
||||
errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "tag", "-f", name))
|
||||
if IsRemote() {
|
||||
|
||||
@@ -23,7 +23,7 @@ func AddGPGPublicKey(t *testing.T) {
|
||||
if fixture.IsLocal() {
|
||||
keyData, err := os.ReadFile(keyPath)
|
||||
require.NoError(t, err)
|
||||
err = os.WriteFile(fmt.Sprintf("%s/app/config/gpg/source/%s", fixture.TmpDir, fixture.GpgGoodKeyID), keyData, 0o644)
|
||||
err = os.WriteFile(fmt.Sprintf("%s/app/config/gpg/source/%s", fixture.TmpDir(), fixture.GpgGoodKeyID), keyData, 0o644)
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
fixture.RestartRepoServer(t)
|
||||
@@ -35,7 +35,7 @@ func DeleteGPGPublicKey(t *testing.T) {
|
||||
args := []string{"gpg", "rm", fixture.GpgGoodKeyID}
|
||||
errors.NewHandler(t).FailOnErr(fixture.RunCli(args...))
|
||||
if fixture.IsLocal() {
|
||||
require.NoError(t, os.Remove(fmt.Sprintf("%s/app/config/gpg/source/%s", fixture.TmpDir, fixture.GpgGoodKeyID)))
|
||||
require.NoError(t, os.Remove(fmt.Sprintf("%s/app/config/gpg/source/%s", fixture.TmpDir(), fixture.GpgGoodKeyID)))
|
||||
} else {
|
||||
fixture.RestartRepoServer(t)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ func DnsFriendly(str string, postfix string) string { //nolint:revive //FIXME(va
|
||||
str = matchFirstCap.ReplaceAllString(str, "${1}-${2}")
|
||||
str = matchAllCap.ReplaceAllString(str, "${1}-${2}")
|
||||
str = strings.ToLower(str)
|
||||
str = strings.ReplaceAll(str, "/", "-")
|
||||
|
||||
if diff := len(str) + len(postfix) - 63; diff > 0 {
|
||||
str = str[:len(str)-diff]
|
||||
|
||||
@@ -134,7 +134,7 @@ func TestAnnotatedTagInStatusSyncRevision(t *testing.T) {
|
||||
Then().
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
And(func(app *Application) {
|
||||
annotatedTagIDOutput, err := fixture.Run(fixture.TmpDir+"/testdata.git", "git", "show-ref", "annotated-tag")
|
||||
annotatedTagIDOutput, err := fixture.Run(fixture.TmpDir()+"/testdata.git", "git", "show-ref", "annotated-tag")
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, annotatedTagIDOutput)
|
||||
// example command output:
|
||||
@@ -142,7 +142,7 @@ func TestAnnotatedTagInStatusSyncRevision(t *testing.T) {
|
||||
annotatedTagIDFields := strings.Fields(string(annotatedTagIDOutput))
|
||||
require.Len(t, annotatedTagIDFields, 2)
|
||||
|
||||
targetCommitID, err := fixture.Run(fixture.TmpDir+"/testdata.git", "git", "rev-parse", "--verify", "annotated-tag^{commit}")
|
||||
targetCommitID, err := fixture.Run(fixture.TmpDir()+"/testdata.git", "git", "rev-parse", "--verify", "annotated-tag^{commit}")
|
||||
// example command output:
|
||||
// "bcd35965e494273355265b9f0bf85075b6bc5163"
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIICijCCAXICAQAwFjEUMBIGA1UEAwwLQXJnbyBDRCBFMkUwggEiMA0GCSqGSIb3
|
||||
DQEBAQUAA4IBDwAwggEKAoIBAQC03Hb4xACw7Y3K90DZizwtUqyVQ/4HgSUIy6OX
|
||||
wG0a+CS9x46FnpUc0divhJh/1jcWn1hkWl5EOopDaPW3jkCw18kz+rDikLfqmXgy
|
||||
bldW92KxoyzSL3wO4VklID6GM6lkdGi0TN/mfNzxNKhjXHm3CbJtkRrrOaUfd5Hj
|
||||
2cbAQmw7hzbn1QYM3sKyKSOF1ySBgvtkakcVEfVFiSAQivKOnSWTMu92Y/cI0nsH
|
||||
zTtMZVL+KPBQ2eTdmMaUxNASnl5rDsR5fqD9GIqVszLakU2N8D2PvyjTUyRVtyiU
|
||||
/et9YBub+/qp7dqKI88nY4tV/sgXpNM+ND8DmbpQFeOZiX0fAgMBAAGgLzAtBgkq
|
||||
hkiG9w0BCQ4xIDAeMBwGA1UdEQQVMBOCEWFyZ29jZC1lMmUtc2VydmVyMA0GCSqG
|
||||
SIb3DQEBCwUAA4IBAQATFrqrM91BKAiOTShf+uMlx8VT11pBtZ78Rg3Enp2xEvUX
|
||||
jEwo3lRD6Fb0T0xi+4O0ScVZFP4yp4ZZ2uqIIzJLSq8F2cko6AhplMPDbxDOVZyq
|
||||
Z5t6VJnfXOQYwtgyowTWCijA5rOaqhmluCbguTQAJRR6Qk6Oc4Ti4BfbliIbzDBO
|
||||
QVAA6HoQPn4E314vBolkxicPesnrYFA7F/U8iCD57cyu5FmEQZuTLmplBzc/UmeV
|
||||
AKcS0+w3Hk+uTgZmqdTWPOzbKXYgF4lU0QNanx4j/H3G4QKujlUspyhid52sFYcq
|
||||
1b4+U2ashtNzUze9Og0Q6CJv3Nu2fqOIG7OBOJcd
|
||||
-----END CERTIFICATE REQUEST-----
|
||||
@@ -1,3 +0,0 @@
|
||||
[localhost]:2222 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLle3IiLWy+Cwz6/JT3K8PSGAEZAJnaxiWk0u9wkAvbZ9wHTffctg25coBa8J4Oo1l5GTIkezib2C4PjCE01BZM=
|
||||
[localhost]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDhRWyu6rg0Kd0ugLxNGZ8gzUjasF4Z0oT16RUC/L9EkJWATAu4TkkoozZ5AcejlS29jUZXTkKt0La4dmIooeMDNd8b5vg1dWzSDDHwxd8Wa/4XZsUlL6zkUFrnqOPaFc/7EwM3I30064zT/Gt0BVvQUxKoT/TTea2KhQqeLmlWh4cVWJBuhZ8YODUf2VD4TSYfvpcqW/jVw2oG8Pj3WIaaG2+Bcp4Q4sJS2K+2kkiqmZ/hiPK1X/UbMRN2zWQBp5UPWFY2ctuC9B8yhLwAyMkHzuWLfB39dNEdn1jTjDsOUWbC3kDsWHsY5gtBxN30NizBWC+83NpaWbrzAlGb0JV1
|
||||
[localhost]:2222 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG2t7Tcavp5oUqbbSwEKRaGwEq94b8BFK16AEBbgRCTp
|
||||
@@ -1,5 +1,6 @@
|
||||
# To prevent regression of https://github.com/argoproj/argo-cd/pull/6253, we
|
||||
# start sshd with -o KexAlgorithms=diffie-hellman-group-exchange-sha256
|
||||
sshd: mkdir -p /var/run/sshd && mkdir -p ~/.ssh && cat ./test/fixture/testrepos/id_rsa.pub > ~/.ssh/authorized_keys && /usr/sbin/sshd -p 2222 -D -e -o KexAlgorithms=diffie-hellman-group-exchange-sha256
|
||||
# Copy fixed SSH host keys so ssh_known_hosts stays valid across container restarts
|
||||
sshd: mkdir -p /var/run/sshd && mkdir -p ~/.ssh && cat ./test/fixture/testrepos/id_rsa.pub > ~/.ssh/authorized_keys && cp ./test/fixture/testrepos/ssh_host_*_key /etc/ssh/ && cp ./test/fixture/testrepos/ssh_host_*_key.pub /etc/ssh/ && chmod 600 /etc/ssh/ssh_host_*_key && /usr/sbin/sshd -p 2222 -D -e -o KexAlgorithms=diffie-hellman-group-exchange-sha256
|
||||
fcgiwrap: fcgiwrap -s unix:/var/run/fcgiwrap.socket & sleep 1 && chmod 777 /var/run/fcgiwrap.socket && wait
|
||||
nginx: nginx -prefix=$(pwd) -g 'daemon off;' -c $(pwd)/test/fixture/testrepos/nginx.conf
|
||||
|
||||
121
test/fixture/testrepos/README.md
Normal file
121
test/fixture/testrepos/README.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Test Repository Server Files
|
||||
|
||||
This directory contains configuration and cryptographic keys for running the E2E test Git server in a Docker container. The server provides Git repositories accessible via SSH, HTTP, and HTTPS.
|
||||
|
||||
## Overview
|
||||
|
||||
The test server runs in Docker (`argoproj/argo-cd-ci-builder:v1.0.0`) using goreman to manage three processes: sshd (port 2222), nginx (ports 9080, 9443-9445), and fcgiwrap (Git HTTP backend).
|
||||
|
||||
## Files
|
||||
|
||||
### `start-git.sh`
|
||||
|
||||
Starts the Docker container with the test Git server. Mounts the current directory and `ARGOCD_E2E_DIR` (default: `/tmp/argo-e2e`), exposing ports for SSH and HTTP/HTTPS access.
|
||||
|
||||
### `start-helm-registry.sh` / `start-authenticated-helm-registry.sh`
|
||||
|
||||
Start Helm registries for testing Helm chart functionality, with and without authentication.
|
||||
|
||||
### `Procfile`
|
||||
|
||||
Defines processes managed by goreman:
|
||||
|
||||
- **sshd**: Copies fixed SSH host keys to `/etc/ssh/` before starting on port 2222
|
||||
- **fcgiwrap**: FastCGI wrapper for Git HTTP backend
|
||||
- **nginx**: Web server for HTTP/HTTPS Git access
|
||||
|
||||
### SSH Keys
|
||||
|
||||
#### SSH Host Keys
|
||||
|
||||
- `ssh_host_rsa_key`, `ssh_host_ecdsa_key`, `ssh_host_ed25519_key` (with `.pub` files)
|
||||
|
||||
By copying pre-generated keys before starting sshd, the same keys are used every time, keeping the `ssh_known_hosts` the same on restarts.
|
||||
|
||||
#### `ssh_known_hosts`
|
||||
|
||||
Contains SSH host key fingerprints for:
|
||||
|
||||
- `[localhost]:2222` - Local development/testing
|
||||
- `[argocd-e2e-server]:2222` - Remote/in-cluster testing
|
||||
|
||||
Both entries have identical fingerprints since they use the same keys from this directory.
|
||||
|
||||
#### `id_rsa.pub`
|
||||
|
||||
Public key added to `~/.ssh/authorized_keys` in the container for SSH authentication.
|
||||
|
||||
### `nginx.conf`
|
||||
|
||||
Provides HTTP (9080), HTTPS (9443/9444/9445), and Helm repository access. Proxies Git operations to git-http-backend via fcgiwrap.
|
||||
|
||||
### `sudoers.conf`
|
||||
|
||||
Sudo configuration allowing test users to start services with elevated privileges.
|
||||
|
||||
## Regenerating SSH Keys
|
||||
|
||||
If you need to regenerate the SSH host keys:
|
||||
|
||||
### 1. Generate New Keys
|
||||
|
||||
```bash
|
||||
cd test/fixture/testrepos
|
||||
|
||||
# Generate RSA key
|
||||
ssh-keygen -t rsa -b 2048 -f ssh_host_rsa_key -N "" -C "root@argocd-e2e"
|
||||
|
||||
# Generate ECDSA key
|
||||
ssh-keygen -t ecdsa -f ssh_host_ecdsa_key -N "" -C "root@argocd-e2e"
|
||||
|
||||
# Generate Ed25519 key
|
||||
ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N "" -C "root@argocd-e2e"
|
||||
```
|
||||
|
||||
### 2. Update ssh_known_hosts
|
||||
|
||||
```bash
|
||||
# Start temporary sshd with new keys
|
||||
sudo mkdir -p /tmp/test-sshd
|
||||
sudo cp ssh_host_*_key* /tmp/test-sshd/
|
||||
sudo chmod 600 /tmp/test-sshd/ssh_host_*_key
|
||||
|
||||
sudo /usr/sbin/sshd -p 2222 \
|
||||
-h /tmp/test-sshd/ssh_host_rsa_key \
|
||||
-h /tmp/test-sshd/ssh_host_ecdsa_key \
|
||||
-h /tmp/test-sshd/ssh_host_ed25519_key \
|
||||
-D &
|
||||
SSHD_PID=$!
|
||||
|
||||
# Scan to get new fingerprints
|
||||
ssh-keyscan -p 2222 localhost > ssh_known_hosts.tmp
|
||||
|
||||
# Stop temporary sshd
|
||||
sudo kill $SSHD_PID
|
||||
sudo rm -rf /tmp/test-sshd
|
||||
|
||||
# Create new ssh_known_hosts with both localhost and argocd-e2e-server entries
|
||||
cat > ssh_known_hosts << 'EOF'
|
||||
# localhost:2222 SSH-2.0-OpenSSH_X.Xp1
|
||||
EOF
|
||||
cat ssh_known_hosts.tmp >> ssh_known_hosts
|
||||
echo "# For in-cluster tests" >> ssh_known_hosts
|
||||
sed 's/\[localhost\]/[argocd-e2e-server]/g' ssh_known_hosts.tmp >> ssh_known_hosts
|
||||
|
||||
rm ssh_known_hosts.tmp
|
||||
```
|
||||
|
||||
### 3. Verify
|
||||
|
||||
```bash
|
||||
# Start the test server
|
||||
./test/fixture/testrepos/start-git.sh
|
||||
|
||||
# In another terminal, test SSH connection
|
||||
ssh -p 2222 -o UserKnownHostsFile=test/fixture/testrepos/ssh_known_hosts root@localhost
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [TLS Certificates](../certs/README.md) - HTTPS certificates (separate from SSH keys)
|
||||
- [Remote Testing](../../remote/README.md) - Running tests against remote clusters
|
||||
@@ -1,6 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# ARGOCD_E2E_DIR can be set to customize the e2e test data directory on the host
|
||||
# This is useful on macOS where Docker doesn't share /tmp with the host
|
||||
# The host directory is mounted to /tmp/argo-e2e inside the container
|
||||
ARGOCD_E2E_DIR="${ARGOCD_E2E_DIR:-/tmp/argo-e2e}"
|
||||
|
||||
docker run --name e2e-git --rm -i \
|
||||
-p 2222:2222 -p 9080:9080 -p 9443:9443 -p 9444:9444 -p 9445:9445 \
|
||||
-w /go/src/github.com/argoproj/argo-cd -v "$(pwd)":/go/src/github.com/argoproj/argo-cd -v /tmp:/tmp docker.io/argoproj/argo-cd-ci-builder:v1.0.0 \
|
||||
-w /go/src/github.com/argoproj/argo-cd \
|
||||
-v /tmp:/tmp \
|
||||
-v "$ARGOCD_E2E_DIR":/tmp/argo-e2e \
|
||||
-v "$(pwd)":/go/src/github.com/argoproj/argo-cd \
|
||||
docker.io/argoproj/argo-cd-ci-builder:v1.0.0 \
|
||||
bash -c "goreman -f ./test/fixture/testrepos/Procfile start"
|
||||
|
||||
Reference in New Issue
Block a user