diff --git a/.github/workflows/deploy-site-task.yml b/.github/workflows/deploy-site-task.yml index 8fd7f9e..3693b28 100644 --- a/.github/workflows/deploy-site-task.yml +++ b/.github/workflows/deploy-site-task.yml @@ -114,7 +114,7 @@ jobs: ENVIRONMENT: ${{ inputs.environment }} run: | set -Eeuo pipefail - rsync -az --mkpath --chmod=D755,F644 \ + rsync -az --mkpath --no-g --chmod=D2755,F644 \ --link-dest="/${ENVIRONMENT}/current/" \ -e "ssh -i ~/.ssh/deploy -o IdentitiesOnly=yes" \ "${RUNNER_TEMP}/bundle/releases/${RELEASE_ID}/" \ diff --git a/.github/workflows/deploy-site.yml b/.github/workflows/deploy-site.yml index f6e689c..773055d 100644 --- a/.github/workflows/deploy-site.yml +++ b/.github/workflows/deploy-site.yml @@ -18,15 +18,8 @@ concurrency: jobs: - # The same gate the pull request and a release run. - validate: - name: Validate sources job - uses: ./.github/workflows/validate-task.yml - permissions: - contents: read - # Staging deploys from any ref, since proving a branch before it merges is what staging is for. - # Asserted before Hugo is installed and before the key reaches the runner. + # First, so a mis-dispatched production deploy fails before anything is installed or written. assert-ref: name: Assert deploy ref job runs-on: ubuntu-latest @@ -39,9 +32,17 @@ jobs: exit 1 fi + # The same gate the pull request and a release run. + validate: + name: Validate sources job + needs: [ assert-ref ] + uses: ./.github/workflows/validate-task.yml + permissions: + contents: read + deploy: name: Deploy site job - needs: [ validate, assert-ref ] + needs: [ validate ] uses: ./.github/workflows/deploy-site-task.yml with: environment: ${{ inputs.environment }} diff --git a/deploy/make-release.sh b/deploy/make-release.sh index 63f9a43..d1e86d9 100755 --- a/deploy/make-release.sh +++ b/deploy/make-release.sh @@ -23,9 +23,14 @@ REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" # The first argument overrides the root, being read after this. DEFAULT_ENV_FILE="$REPO/secrets/.env" ENV_FILE="${ENV_FILE:-$DEFAULT_ENV_FILE}" -# Anchored under the repo, so a relative name resolves the same from any working directory. +# A relative name resolves against the repo, so it means the same from any working directory. +# Traversal is refused rather than resolved, since a relative name is meant to reach secrets/. case "$ENV_FILE" in /*) ;; +*..*) + echo "ENV_FILE must not traverse: $ENV_FILE" >&2 + exit 1 + ;; *) ENV_FILE="$REPO/$ENV_FILE" ;; esac if [ -f "$ENV_FILE" ]; then