diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b07c1196c..14f3f4e91 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,6 +2,10 @@ name: Test, Build, Publish on: push: + branches: + - '**' + tags: + - 'v**' pull_request: workflow_dispatch: inputs: @@ -112,7 +116,13 @@ jobs: packages: write strategy: matrix: - image: [nginx, service] + image: + - postgres14 + - postgres + - service + - nginx + - secrets + - enketo env: REGISTRY: ghcr.io steps: @@ -144,11 +154,12 @@ jobs: uses: docker/setup-buildx-action@v4 - name: Build and push ${{ matrix.image }} Docker image - uses: docker/build-push-action@v7 + uses: docker/bake-action@v7 with: - file: ${{ matrix.image }}.dockerfile - context: . + files: docker-compose.yml + targets: ${{ matrix.image }} push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: 'linux/amd64,linux/arm64' + set: | + *.labels=${{ steps.meta.outputs.labels }} + *.tags=${{ steps.meta.outputs.tags }} + *.platform=linux/amd64,linux/arm64 diff --git a/docker-compose.yml b/docker-compose.yml index 627eeea1d..1e8d67b71 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,6 @@ services: postgres14: - build: - context: . - dockerfile: postgres14.dockerfile + image: 'ghcr.io/getodk/central-postgres14:v0.0.1-testing-3' shm_size: 512m volumes: - postgres14:/var/lib/odk/postgresql/14 @@ -14,9 +12,7 @@ services: postgres: # This service upgrades from postgres 9.6 to 14. # The legacy name must be maintained to allow access to the anonymous volume. - build: - context: . - dockerfile: postgres-upgrade.dockerfile + image: 'ghcr.io/getodk/central-postgres:v0.0.1-testing-3' platform: linux/amd64 volumes: - /var/lib/postgresql/data @@ -36,9 +32,7 @@ services: - DKIM_KEY_PATH=/etc/exim4/dkim.key.temp restart: always service: - build: - context: . - dockerfile: service.dockerfile + image: 'ghcr.io/getodk/central-service:v0.0.1-testing-3' depends_on: - secrets - postgres14 @@ -93,9 +87,7 @@ services: logging: driver: local nginx: - build: - context: . - dockerfile: nginx.dockerfile + image: 'ghcr.io/getodk/central-nginx:v0.0.1-testing-3' depends_on: - service - enketo @@ -125,18 +117,14 @@ services: image: 'ghcr.io/getodk/pyxform-http:v4.4.1' restart: always secrets: + image: 'ghcr.io/getodk/central-secrets:v0.0.1-testing-3' volumes: - secrets:/etc/secrets - build: - context: . - dockerfile: secrets.dockerfile command: './generate-secrets.sh' enketo: + image: 'ghcr.io/getodk/central-enketo:v0.0.1-testing-3' volumes: - secrets:/etc/secrets - build: - context: . - dockerfile: enketo.dockerfile restart: always depends_on: - secrets diff --git a/snapshot-compose.sh b/snapshot-compose.sh new file mode 100755 index 000000000..069b4c193 --- /dev/null +++ b/snapshot-compose.sh @@ -0,0 +1,8 @@ +#!/bin/bash -eu +set -o pipefail +shopt -s inherit_errexit + +docker compose \ + --file docker-compose.yml \ + --file snapshots.docker-compose.yml \ + "$@" diff --git a/snapshots.docker-compose.yml b/snapshots.docker-compose.yml new file mode 100644 index 000000000..481dfb8de --- /dev/null +++ b/snapshots.docker-compose.yml @@ -0,0 +1,19 @@ +services: + postgres14: + build: + dockerfile: postgres14.dockerfile + postgres: + build: + dockerfile: postgres-upgrade.dockerfile + service: + build: + dockerfile: service.dockerfile + nginx: + build: + dockerfile: nginx.dockerfile + secrets: + build: + dockerfile: secrets.dockerfile + enketo: + build: + dockerfile: enketo.dockerfile diff --git a/tag-release.sh b/tag-release.sh new file mode 100755 index 000000000..3b79d5a90 --- /dev/null +++ b/tag-release.sh @@ -0,0 +1,88 @@ +#!/bin/bash -eu +set -o pipefail +shopt -s inherit_errexit + +log() { echo "[release] $*"; } + +log "Checking git branch..." +currentBranch="$(git rev-parse --abbrev-ref HEAD)" +if [[ "$currentBranch" = master ]]; then + log "!!!" + log "!!! Unexpected branch: $currentBranch" + log "!!!" + log "!!! This script should NOT be run on the master branch." + log "!!!" + exit 1 +fi +log " Git branch OK." + +log "Checking for uncommitted changes..." +gitStatus="$(git status --porcelain)" +if [[ "$gitStatus" != "" ]]; then + log "!!!" + log "!!! Your working directory is dirty. Make sure you have committed all changes." + log "!!!" + exit 1 +fi +log " No uncommitted changes found." + +log "Checking for divergence from upstream..." +upstream="$(git rev-parse --abbrev-ref '@{upstream}')" +remote="${upstream%%/*}" +log " Fetching from remote '$remote'..." +git fetch "$remote" +log " Comparing to $upstream..." +if ! git diff --exit-code "$upstream"..HEAD; then + log "!!!" + log "!!! Differences found between HEAD and tracking branch $upstream !!!" + log "!!!" + log "!!! Do you need to git push?" + log "!!!" + exit 1 +fi +log " HEAD seems to be in-line with upstream." + +year="$(date +%Y)" +if git tag | grep "^v$year\."; then + lastMinor="$(git tag | grep "^v$year" | tail -n1 | cut -d'.' -f2)" + suggestedVersion="v$year.$((lastMinor+1)).0" +else + suggestedVersion="v$year.1.0" +fi +read -r -e \ + -p "[release] Version to release: " \ + -i "$suggestedVersion" newVersion +if ! [[ "$newVersion" = v*.*.* ]]; then + log "!!!" + log "!!! Version '$newVersion' does not match expected format." + log "!!!" + exit 1 +fi + +log "Updating version numbers in docker-compose.yml ..." +tmpfile="$(mktemp)" +sed -E \ + -e "s_(image:\s+'.*/.*/central-postgres14):.*'_\1:$newVersion'_" \ + -e "s_(image:\s+'.*/.*/central-postgres):.*'_\1:$newVersion'_" \ + -e "s_(image:\s+'.*/.*/central-nginx):.*'_\1:$newVersion'_" \ + -e "s_(image:\s+'.*/.*/central-service):.*'_\1:$newVersion'_" \ + -e "s_(image:\s+'.*/.*/central-secrets):.*'_\1:$newVersion'_" \ + -e "s_(image:\s+'.*/.*/central-enketo):.*'_\1:$newVersion'_" \ + docker-compose.yml > "$tmpfile" +mv "$tmpfile" docker-compose.yml + +log "Committing changes to git..." +git add docker-compose.yml +git commit -m"Release version: $newVersion" +git tag "$newVersion" + +log "Pushing release to git..." +git push && git push --tags + +echo +log "Release tagging complete. Check build progress at:" +log "" +log " https://github.com/getodk/central/actions" +log "" +log "Once GitHub Actions has uploaded all images, master branch can be updated." +echo diff --git a/test/test-images.sh b/test/test-images.sh index bb30278b5..587c1c042 100755 --- a/test/test-images.sh +++ b/test/test-images.sh @@ -14,7 +14,7 @@ check_path() { for (( i=0; ; ++i )); do log "Checking response from $requestPath ..." echo -e "GET $requestPath HTTP/1.0\r\nHost: local\r\n\r\n" | - docker compose exec --no-TTY nginx \ + ./snapshot-compose.sh exec --no-TTY nginx \ openssl s_client -quiet -connect 127.0.0.1:443 \ >"$tmp" 2>&1 || true if grep --silent --fixed-strings "$expected" "$tmp"; then @@ -44,10 +44,10 @@ SYSADMIN_EMAIL=no-reply@getodk.org' > .env touch ./files/allow-postgres14-upgrade log "Building docker containers..." -docker compose build +./snapshot-compose.sh build log "Starting containers..." -docker compose up --detach +./snapshot-compose.sh up --detach log "Verifying version.txt..." diff \ diff --git a/test/test-secrets.sh b/test/test-secrets.sh index 6bb7fedb4..e1f06d6a3 100755 --- a/test/test-secrets.sh +++ b/test/test-secrets.sh @@ -12,10 +12,10 @@ if [[ -d "$localSecrets" ]]; then fi log "Building secrets image..." -docker compose build --no-cache secrets +./snapshot-compose.sh build --no-cache secrets log "Running container..." -docker compose run --rm --volume "$localSecrets":/etc/secrets secrets +./snapshot-compose.sh run --rm --volume "$localSecrets":/etc/secrets secrets log "Checking secrets exist..." assert_size() {