Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Integration Tests
on:
pull_request:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
setup-integration-test:
runs-on: ubuntu-latest
outputs:
versions: ${{ steps.versions.outputs.versions }}
steps:
- uses: actions/checkout@v4
- id: versions
working-directory: ./integration
# The `jq` command is "output compact, raw input, slurp, split on new lines, and remove the last element". This results in a JSON array of Connect versions (e.g., ["2025.01.0", "2024.12.0"]).
run: |
versions=$(make print-versions | jq -c -Rs 'split("\n") | .[:-1]')
echo "versions=$versions" >> "$GITHUB_OUTPUT"

integration-test:
runs-on: ubuntu-latest
needs: setup-integration-test
strategy:
fail-fast: false
matrix:
CONNECT_VERSION: ${{ fromJson(needs.setup-integration-test.outputs.versions) }}
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Write Posit Connect license to disk
run: echo "$RSC_LICENSE" > ./integration/license.lic
env:
CONNECT_LICENSE: ${{ secrets.RSC_LICENSE }}
- uses: astral-sh/setup-uv@v6
- run: uv python install
- run: make -C ./integration ${{ matrix.CONNECT_VERSION }}
- uses: actions/upload-artifact@v4
if: always()
with:
name: ${{ matrix.CONNECT_VERSION }} - Integration Test Report
path: integration/reports/*.xml

integration-test-report:
needs: integration-test
runs-on: ubuntu-latest
permissions:
checks: write
pull-requests: write
if: always()
steps:
- uses: actions/download-artifact@v4
with:
path: artifacts
- uses: EnricoMi/publish-unit-test-result-action@v2
with:
check_name: integration-test-results
comment_mode: off
files: "artifacts/**/*.xml"
report_individual_runs: true
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ docs-clean:
requirements/dev.txt: pyproject.toml
@# allows you to do this...
@# make requirements | tee > requirements/some_file.txt
@pip-compile pyproject.toml --rebuild --extra doc --extra test --extra check --output-file=- > $@
@uv pip compile pyproject.toml --extra doc --extra test --extra check --output-file $@

binder/requirements.txt: requirements/dev.txt
cp $< $@
Expand Down
3 changes: 3 additions & 0 deletions integration/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
logs
reports
license.lic
146 changes: 146 additions & 0 deletions integration/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
PROJECT_NAME ?= pins

# Docker settings
DOCKER_COMPOSE ?= docker compose
DOCKER_CONNECT_IMAGE ?= rstudio/rstudio-connect
DOCKER_PROJECT_IMAGE_TAG ?= $(PROJECT_NAME):latest

# Connect settings
CONNECT_BOOTSTRAP_SECRETKEY ?= $(shell head -c 32 /dev/random | base64)

# pytest settings
PYTEST_ARGS ?= "-s"

.DEFAULT_GOAL := latest

.PHONY: $(CONNECT_VERSIONS) \
all \
build \
down \
down-% \
latest \
test \
up \
up-% \
help

# Versions
CONNECT_VERSIONS := \
2025.07.0 \
2025.06.0 \
2025.05.0 \
2025.04.0 \
2025.03.0 \
2025.02.0 \
2025.01.0 \
2024.12.0 \
2024.11.0 \
2024.09.0 \
2024.08.0 \
2024.06.0 \
2024.05.0 \
2024.04.1 \
2024.04.0 \
2024.03.0 \
2024.02.0 \
2024.01.0 \
2023.12.0 \
2023.10.0 \
2023.09.0 \
2023.07.0 \
2023.06.0 \
2023.05.0 \
2023.01.1 \
2023.01.0 \
2022.12.0 \
2022.11.0

clean:
rm -rf logs reports
find . -type d -empty -delete

# Run test suite for a specific Connect version.
$(CONNECT_VERSIONS): %: down-% up-%

# Run test suite against all Connect versions.
all: $(CONNECT_VERSIONS:%=%) preview

# Run test suite against latest Connect version.
latest:
$(MAKE) $(firstword $(CONNECT_VERSIONS))

# Run test suite against preview Connect version.
preview:
$(MAKE) \
DOCKER_CONNECT_IMAGE=rstudio/rstudio-connect-preview \
DOCKER_CONNECT_IMAGE_TAG=dev-jammy-daily \
down-preview up-preview

# Build Dockerfile
build:
make -C .. $(UV_LOCK)
docker build -t $(DOCKER_PROJECT_IMAGE_TAG) ..

# Tear down resources.
down: $(CONNECT_VERSIONS:%=down-%)
down-%: DOCKER_CONNECT_IMAGE_TAG=jammy-$*
down-%: CONNECT_VERSION=$*
down-%:
CONNECT_BOOTSTRAP_SECRETKEY=$(CONNECT_BOOTSTRAP_SECRETKEY) \
CONNECT_VERSION=$* \
DOCKER_CONNECT_IMAGE_TAG=$(DOCKER_CONNECT_IMAGE_TAG) \
DOCKER_CONNECT_IMAGE=$(DOCKER_CONNECT_IMAGE) \
DOCKER_PROJECT_IMAGE_TAG=$(DOCKER_PROJECT_IMAGE_TAG) \
PYTEST_ARGS="$(PYTEST_ARGS)" \
$(DOCKER_COMPOSE) -p $(PROJECT_NAME)-$(subst .,-,$(CONNECT_VERSION)) down -v

# Create, start, and run Docker Compose.
up: $(CONNECT_VERSIONS:%=up-%)
up-%: CONNECT_VERSION=$*
up-%: DOCKER_CONNECT_IMAGE_TAG=jammy-$*
up-%: build
CONNECT_BOOTSTRAP_SECRETKEY=$(CONNECT_BOOTSTRAP_SECRETKEY) \
CONNECT_VERSION=$* \
DOCKER_CONNECT_IMAGE_TAG=$(DOCKER_CONNECT_IMAGE_TAG) \
DOCKER_CONNECT_IMAGE=$(DOCKER_CONNECT_IMAGE) \
DOCKER_PROJECT_IMAGE_TAG=$(DOCKER_PROJECT_IMAGE_TAG) \
PYTEST_ARGS="$(PYTEST_ARGS)" \
$(DOCKER_COMPOSE) -p $(PROJECT_NAME)-$(subst .,-,$(CONNECT_VERSION)) up -V --abort-on-container-exit --no-build

# Show available versions
print-versions:
@printf "%s\n" $(strip $(CONNECT_VERSIONS))

# Show help message.
help:
@echo "Makefile Targets:"
@echo " all (default) Run test suite for all Connect versions."
@echo " latest Run test suite for latest Connect version."
@echo " preview Run test suite for preview Connect version."
@echo " <version> Run test suite for the specified Connect version. (e.g., make 2024.05.0)"
@echo " up Start Docker Compose for all Connect versions."
@echo " down Tear down Docker resources for all Connect versions."
@echo " clean Clean up the project directory."
@echo " print-versions Show the available Connect versions."
@echo " help Show this help message."
@echo
@echo "Common Usage:"
@echo " make -j 4 Run test suite in parallel for all Connect versions."
@echo " make latest Run test suite for latest Connect version."
@echo " make preview Run test suite for preview Connect version."
@echo " make 2024.05.0 Run test suite for specific Connect version."
@echo
@echo "Environment Variables:"
@echo " DOCKER_COMPOSE Command to invoke Docker Compose. Default: docker compose"
@echo " DOCKER_CONNECT_IMAGE Docker image name for Connect. Default: rstudio/rstudio-connect"
@echo " DOCKER_PROJECT_IMAGE_TAG Docker image name and tag for the project image. Default: $(PROJECT_NAME):latest"
@echo " PYTEST_ARGS Arguments to pass to pytest. Default: \"-s\""

# Run tests.
test:
mkdir -p logs
set -o pipefail; \
CONNECT_VERSION=${CONNECT_VERSION} \
CONNECT_API_KEY="$(shell $(UV) run rsconnect bootstrap -i -s http://connect:3939 --raw)" \
echo "Hello, World!" | \
tee ./integration/logs/$(CONNECT_VERSION).log;
46 changes: 46 additions & 0 deletions integration/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
services:
tests:
image: ${DOCKER_PROJECT_IMAGE_TAG}
# Run integration test suite.
#
# Target is relative to the ./integration directory, not the project root
# directory. The execution base directory is determined by the 'WORKDIR'
# in the Dockerfile.
command: make -C ./integration test
environment:
- CONNECT_BOOTSTRAP_SECRETKEY=${CONNECT_BOOTSTRAP_SECRETKEY}
# Port 3939 is the default port for Connect
- CONNECT_SERVER=http://connect:3939
- CONNECT_VERSION=${CONNECT_VERSION}
- PYTEST_ARGS=${PYTEST_ARGS}
volumes:
- .:/sdk/integration
depends_on:
connect:
condition: service_healthy
networks:
- test
connect:
image: ${DOCKER_CONNECT_IMAGE}:${DOCKER_CONNECT_IMAGE_TAG}
pull_policy: always
environment:
- CONNECT_BOOTSTRAP_ENABLED=true
- CONNECT_BOOTSTRAP_SECRETKEY=${CONNECT_BOOTSTRAP_SECRETKEY}
- CONNECT_APPLICATIONS_PACKAGEAUDITINGENABLED=true
- CONNECT_TENSORFLOW_ENABLED=false
networks:
- test
privileged: true
volumes:
- /var/lib/rstudio-connect
- ./license.lic:/var/lib/rstudio-connect/rstudio-connect.lic:ro
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3939"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s

networks:
test:
driver: bridge
Loading
Loading