正規表現5〜10番のパズル問題を追加 #35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Supply Chain CI | |
| on: | |
| push: | |
| pull_request: | |
| schedule: | |
| - cron: "15 11 * * 2" | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| source: | |
| name: Workflow, secrets and dependencies | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 15 | |
| env: | |
| PYTHONPATH: backend | |
| GRYPE_CHECK_FOR_APP_UPDATE: "false" | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| fetch-depth: 0 | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: "3.14" | |
| - name: Install locked development dependencies | |
| run: | | |
| python -m pip install poetry==2.4.1 | |
| poetry check --lock | |
| poetry install --no-interaction | |
| - name: Install verified scanners | |
| run: | | |
| python ci/install_tools.py "$RUNNER_TEMP/soj-tools" actionlint gitleaks syft grype | |
| printf 'GRYPE_DB_CACHE_DIR=%s/grype-db\n' "$RUNNER_TEMP" >> "$GITHUB_ENV" | |
| - name: Validate workflows and policy | |
| run: | | |
| "$RUNNER_TEMP/soj-tools/actionlint" | |
| poetry run pytest backend/tests/test_ci_policy.py backend/tests/test_supply_chain.py backend/tests/test_deployment.py backend/tests/test_rootless_ci.py | |
| - name: Scan complete Git history and current files | |
| run: | | |
| "$RUNNER_TEMP/soj-tools/gitleaks" git . --redact=100 --no-banner --log-opts=--all | |
| "$RUNNER_TEMP/soj-tools/gitleaks" dir . --redact=100 --no-banner | |
| - name: Update vulnerability database | |
| run: | | |
| "$RUNNER_TEMP/soj-tools/grype" db update | |
| - name: Verify scanner failure detection | |
| run: poetry run python ci/supply_chain.py fixtures --tools "$RUNNER_TEMP/soj-tools" --reports "$RUNNER_TEMP/scanner-fixtures" | |
| - name: Scan lock files and generate SBOMs | |
| id: scan | |
| run: poetry run python ci/supply_chain.py source --tools "$RUNNER_TEMP/soj-tools" --reports "$RUNNER_TEMP/dependency-reports" | |
| - name: Retain dependency reports even when vulnerabilities block the job | |
| if: ${{ always() && steps.scan.outcome != 'skipped' }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: dependency-reports | |
| path: ${{ runner.temp }}/dependency-reports/ | |
| retention-days: 14 | |
| if-no-files-found: error | |
| runtime: | |
| name: Rootless runtime E2E and image scan | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 45 | |
| env: | |
| PYTHONPATH: backend | |
| GRYPE_CHECK_FOR_APP_UPDATE: "false" | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: "3.14" | |
| - name: Install locked development dependencies | |
| run: | | |
| python -m pip install poetry==2.4.1 | |
| poetry check --lock | |
| poetry install --no-interaction | |
| - name: Prepare user systemd and D-Bus for rootless cgroups | |
| run: bash ci/prepare_rootless.sh | |
| - name: Set up isolated rootless Docker | |
| uses: docker/setup-docker-action@77e84dbf09b47d1e29270283c22f16145aa85ca1 # v5.4.0 | |
| with: | |
| version: v29.7.2 | |
| rootless: true | |
| set-host: true | |
| - name: Validate rootless daemon and build current targets | |
| env: | |
| VITE_X_URL: ${{ vars.VITE_X_URL || 'https://x.com/yusukekato_main' }} | |
| VITE_GITHUB_REPO_URL: ${{ vars.VITE_GITHUB_REPO_URL || 'https://github.com/YusukeKato/ShellgeiOnlineJudge' }} | |
| VITE_GITHUB_AUTHOR_URL: ${{ vars.VITE_GITHUB_AUTHOR_URL || 'https://github.com/YusukeKato' }} | |
| VITE_BLOG_URL: ${{ vars.VITE_BLOG_URL || 'https://yusukekato.jp' }} | |
| VITE_MIXI2_URL: ${{ vars.VITE_MIXI2_URL || 'https://mixi.social/communities/dcf8e9d8-a6c4-40a9-8e05-328b4424f886/about' }} | |
| run: | | |
| poetry run python -c 'from ci.supply_chain import rootless; rootless()' | |
| docker build --file deploy/sandbox/Dockerfile --tag soj-sandbox:ci . | |
| printf 'SANDBOX_IMAGE_ID=%s\n' "$(docker image inspect soj-sandbox:ci --format '{{.Id}}')" >> "$GITHUB_ENV" | |
| docker build --file backend/Dockerfile --target backend --tag soj-backend:ci . | |
| # 長いbuild・scanの前に、実際に資源制限付きcontainerを起動できるか検証する。 | |
| poetry run python -c 'import subprocess; from ci.supply_chain import inspect_python_runtime; image = subprocess.check_output(["docker", "image", "inspect", "soj-backend:ci", "--format", "{{.Id}}"], text=True).strip(); print(inspect_python_runtime(image))' | |
| docker build --file backend/Dockerfile --target runner --tag soj-runner:ci . | |
| # 検証・配備するfrontend imageに、日本時間のbuild日を埋め込む。 | |
| VITE_UPDATE_DATE="$(TZ=Asia/Tokyo date +%F)" | |
| export VITE_UPDATE_DATE | |
| docker build --file frontend/Dockerfile --build-arg VITE_SOJ_URL= \ | |
| --build-arg VITE_UPDATE_DATE --build-arg VITE_X_URL --build-arg VITE_GITHUB_REPO_URL \ | |
| --build-arg VITE_GITHUB_AUTHOR_URL --build-arg VITE_BLOG_URL --build-arg VITE_MIXI2_URL \ | |
| --tag soj-frontend:ci . | |
| docker build --file deploy/postgres/Dockerfile --tag soj-db:ci . | |
| docker build --file backend/tests/integration/browser/Dockerfile --tag soj-browser:ci . | |
| - name: Install verified inventory and vulnerability tools | |
| run: | | |
| python ci/install_tools.py "$RUNNER_TEMP/soj-tools" syft grype | |
| printf 'GRYPE_DB_CACHE_DIR=%s/grype-db\n' "$RUNNER_TEMP" >> "$GITHUB_ENV" | |
| - name: Update vulnerability database | |
| run: | | |
| "$RUNNER_TEMP/soj-tools/grype" db update | |
| - name: Scan runtime images and prepare candidate archive | |
| id: scan | |
| run: poetry run python ci/supply_chain.py runtime --tools "$RUNNER_TEMP/soj-tools" --reports "$RUNNER_TEMP/runtime-reports" --sandbox "$SANDBOX_IMAGE_ID" | |
| - name: Pull verified infrastructure images | |
| run: | | |
| poetry run python -c 'import subprocess; from tests.postgres_support import upstream_postgres_image; refs = [upstream_postgres_image()]; [subprocess.run(["docker", "pull", ref], check=True) for ref in refs]' | |
| - name: Full Compose regression and image boundary checks | |
| env: | |
| SOJ_RUN_DOCKER_TESTS: "1" | |
| SOJ_RUN_COMPOSE_E2E: "1" | |
| SOJ_RUN_FULL_REGRESSION: "1" | |
| SOJ_RUN_RUNTIME_IMAGE_TESTS: "1" | |
| SOJ_DB_IMAGE: soj-db:ci | |
| SOJ_COMPOSE_BACKEND_IMAGE: soj-backend:ci | |
| SOJ_COMPOSE_RUNNER_IMAGE: soj-runner:ci | |
| SOJ_COMPOSE_FRONTEND_IMAGE: soj-frontend:ci | |
| SOJ_COMPOSE_BROWSER_IMAGE: soj-browser:ci | |
| SOJ_BACKEND_RUNTIME_IMAGE: soj-backend:ci | |
| SOJ_RUNNER_RUNTIME_IMAGE: soj-runner:ci | |
| run: poetry run pytest backend/tests/integration/test_compose_e2e.py backend/tests/integration/test_production_deploy.py backend/tests/integration/test_runtime_images.py backend/tests/integration/test_postgres_image.py backend/tests/integration/test_sandbox_tools.py | |
| - name: Retain runtime inventory and candidate for review | |
| if: ${{ always() && steps.scan.outcome != 'skipped' }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: runtime-reports | |
| path: ${{ runner.temp }}/runtime-reports/ | |
| retention-days: 14 | |
| if-no-files-found: error | |
| compression-level: 0 | |
| provenance: | |
| name: Attest reviewed main artifacts | |
| needs: [source, runtime] | |
| if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: read | |
| id-token: write | |
| attestations: write | |
| steps: | |
| # このjobはcheckoutや取得artifact内のcode実行を行わない。 | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| pattern: "*-reports" | |
| path: ${{ runner.temp }}/attestation-subjects | |
| - uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2 | |
| with: | |
| subject-path: ${{ runner.temp }}/attestation-subjects/**/* | |
| create-storage-record: false |