diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..dba12a0 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,24 @@ +name: Run Integration test + +on: + push: + pull_request: + +jobs: + integration-test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - run: docker compose up -d + working-directory: test + - run: test/await_healthy.sh + - uses: ./ + name: Run test + with: + GL_SERVER_URL: http://127.0.0.1:8080 + GL_PROJECT_ID: '1000' + GL_RUNNER_TOKEN: some_long_runner_token + GL_API_TOKEN: TEST1234567890123456 + - run: docker compose down + working-directory: test diff --git a/lib/action/pipeline_awaiter.rb b/lib/action/pipeline_awaiter.rb index cc7743e..32448fb 100644 --- a/lib/action/pipeline_awaiter.rb +++ b/lib/action/pipeline_awaiter.rb @@ -26,6 +26,7 @@ def wait! puts "Pipeline succeeded in #{duration} minutes!" return else + puts puts "Pipeline #{status} in #{duration} minutes!" raise PipelineFailed, 'Pipeline did not succeed!' end diff --git a/lib/action/step/start_runner.rb b/lib/action/step/start_runner.rb index fa7f5e3..fd692e4 100644 --- a/lib/action/step/start_runner.rb +++ b/lib/action/step/start_runner.rb @@ -13,6 +13,7 @@ def execute 'Binds' => [ '/var/run/docker.sock:/var/run/docker.sock:ro' ], + 'NetworkMode' => 'host' } ) diff --git a/test/await_healthy.sh b/test/await_healthy.sh new file mode 100755 index 0000000..d0088dd --- /dev/null +++ b/test/await_healthy.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +CONTAINER_ENGINE="${CONTAINER_ENGINE:-docker}" +GITLAB_BASE_URL="${GITLAB_BASE_URL:-http://127.0.0.1:8080}" + +set -e + +if [ "$CONTAINER_ENGINE" != "docker" ]; then + echo "Using container engine $CONTAINER_ENGINE" +fi + +printf 'Waiting for GitLab container to become healthy' + +until test -n "$($CONTAINER_ENGINE ps --quiet --filter label=gitlab-pipeline-action/owned --filter health=healthy)"; do + printf '.' + sleep 5 +done + +echo +echo "GitLab is healthy at $GITLAB_BASE_URL" + +# Print the version, since it is useful debugging information. +curl --silent --show-error --header "Private-Token: TEST1234567890123456" "$GITLAB_BASE_URL/api/v4/version" + +echo +printf 'Waiting for Test project to be imported' + +import_status="" +while [[ "$import_status" != "finished" ]]; do + printf '.' + import_status=$(curl --silent --show-error --header "Private-Token: TEST1234567890123456" "$GITLAB_BASE_URL/api/v4/projects/1000" | jq -r .import_status) + sleep 5 +done + +echo diff --git a/test/docker-compose.yml b/test/docker-compose.yml new file mode 100644 index 0000000..3fa0f5a --- /dev/null +++ b/test/docker-compose.yml @@ -0,0 +1,19 @@ +services: + gitlab-ce: + image: gitlab/gitlab-ce:${GITLAB_CE_VERSION:-latest} + restart: always + ports: + - 8080:80 + environment: + GITLAB_ROOT_PASSWORD: routrout + GITLAB_OMNIBUS_CONFIG: | + external_url 'http://127.0.0.1:8080' + nginx[:listen_port] = 80 + labels: + gitlab-pipeline-action/owned: '' + volumes: + - ./healthcheck_and_setup.sh:/healthcheck_and_setup.sh:Z + healthcheck: + test: /healthcheck_and_setup.sh + interval: 10s + timeout: 3m diff --git a/test/healthcheck_and_setup.sh b/test/healthcheck_and_setup.sh new file mode 100755 index 0000000..d67a032 --- /dev/null +++ b/test/healthcheck_and_setup.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env sh + +# This script is intended to be used as a Docker HEALTHCHECK for the GitLab container. +# It prepares GitLab prior to running tests. +# +# This is a known workaround for docker-compose lacking lifecycle hooks. +# See: https://github.com/docker/compose/issues/1809#issuecomment-657815188 + +set -e + +# Check for a successful HTTP status code from GitLab. +curl --silent --show-error --fail --output /dev/null 127.0.0.1:80 + +# Because this script runs on a regular health check interval, +# this file functions as a marker that tells us if initialization already finished. +done=/var/gitlab-test-initialized + +test -f $done || { + echo 'Initializing GitLab for tests' + + echo 'Creating access token' + ( + printf 'token = PersonalAccessToken.create(' + printf 'user_id: 1, ' + printf 'scopes: [:api, :write_repository], ' + printf 'expires_at: Time.now + 30.days, ' + printf 'name: :token);' + printf "token.set_token('TEST1234567890123456');" + printf 'token.save!;' + + printf 'settings = ApplicationSetting.current;' + printf 'settings.import_sources << "git";' + printf 'settings.save!;' + + printf 'Projects::CreateService.new(User.find(1), {' + printf 'namespace_id: User.first.namespace.id,' + printf 'name: "Test",' + printf 'path: "test",' + printf 'id: 1000,' + printf 'import_type: "git",' + printf 'import_url: "https://github.com/Taucher2003/Gitlab-Pipeline-Action.git"' + printf '}).execute;' + + printf 'Ci::Runners::CreateRunnerService.new(' + printf 'user: User.first,' + printf 'params: {' + printf 'runner_type: "instance_type",' + printf 'token: "some_long_runner_token"' + printf '}' + printf ').execute;' + + printf 'Ci::ChangeVariableService.new(' + printf 'container: Project.find(1000),' + printf 'current_user: User.first,' + printf 'params: { action: :create, variable_params: { key: "GIT_STRATEGY", value: "none", protected: false } }' + printf ').execute;' + ) | gitlab-rails console + + touch $done +} + +echo 'GitLab is ready for tests'