From a8db988ecd3258e52683d18d60e4ea1534d071a6 Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Sun, 28 May 2023 15:31:52 +0200 Subject: [PATCH] [CI] Forgejo Actions based CI for PR & branches (cherry picked from commit f9d75d4705ece5c119f2fd5e2bfbaf630d0bf739) (cherry picked from commit 64f76f4ab269daa6a584305164732c68be0161c5) (cherry picked from commit 5d024541551f1be98444923f0fa327a855104725) [CI] Forgejo Actions workflows (cherry picked from commit 3ff59b5379ebf761f32875f9d869a1d18f79741c) (cherry picked from commit 8af826a6f7c70d03079ec68f10230041695017cd) (cherry picked from commit d7c09d9cc80037a28d488da142ae2a2a99f59ac9) [CI] use the docker label instead of ubuntu-latest (cherry picked from commit b6a6470db6c8bae9963e204f9c8c408f309e81e3) [CI] all tests need compliance before proceeding (cherry picked from commit b35c496f2c3034164b9bb3a3550f35026adf9372) (cherry picked from commit 36a4148a8ec654ae9fa5a6925a3b8606b96aebcc) (cherry picked from commit 7ffcffa653808a284f422fdc31f6ea07874b585d) (cherry picked from commit 8a246d296e502c181c6ee779d1773c9e78ca7acf) (cherry picked from commit 4b5d14ab8dce389e88ddf457d81544c8a40b821e) (cherry picked from commit 98dfb019a4a4f4cae4e51535a96e7512ee47b4db) (cherry picked from commit f0d3f5327526dd2bd1dd1d4fc8abcdd30926bc2c) --- .forgejo/workflows/testing.yml | 152 ++++++++++++++ .github/workflows/cron-licenses.yml | 28 --- .github/workflows/cron-lock.yml | 22 -- .github/workflows/cron-translations.yml | 49 ----- .github/workflows/pull-compliance.yml | 140 ------------- .github/workflows/pull-db-tests.yml | 247 ----------------------- .github/workflows/pull-docker-dryrun.yml | 23 --- .github/workflows/pull-e2e-tests.yml | 32 --- 8 files changed, 152 insertions(+), 541 deletions(-) create mode 100644 .forgejo/workflows/testing.yml delete mode 100644 .github/workflows/cron-licenses.yml delete mode 100644 .github/workflows/cron-lock.yml delete mode 100644 .github/workflows/cron-translations.yml delete mode 100644 .github/workflows/pull-compliance.yml delete mode 100644 .github/workflows/pull-db-tests.yml delete mode 100644 .github/workflows/pull-docker-dryrun.yml delete mode 100644 .github/workflows/pull-e2e-tests.yml diff --git a/.forgejo/workflows/testing.yml b/.forgejo/workflows/testing.yml new file mode 100644 index 0000000000..22e73f5378 --- /dev/null +++ b/.forgejo/workflows/testing.yml @@ -0,0 +1,152 @@ +name: testing + +on: + pull_request: + push: + branches: + - 'forgejo*' + - 'v*/forgejo*' + +jobs: + lint-backend: + runs-on: docker + steps: + - uses: https://code.forgejo.org/actions/checkout@v3 + - uses: https://code.forgejo.org/actions/setup-go@v4 + with: + go-version: ">=1.20" + check-latest: true + - run: make deps-backend deps-tools + - run: make lint-backend + env: + TAGS: bindata sqlite sqlite_unlock_notify + checks-backend: + runs-on: docker + steps: + - uses: https://code.forgejo.org/actions/checkout@v3 + - uses: https://code.forgejo.org/actions/setup-go@v4 + with: + go-version: ">=1.20" + check-latest: true + - run: make deps-backend deps-tools + - run: make --always-make checks-backend # ensure the "go-licenses" make target runs + test-unit: + runs-on: docker + needs: [lint-backend, checks-backend] + container: + image: codeberg.org/forgejo/test_env:main + steps: + - uses: https://code.forgejo.org/actions/checkout@v3 + - uses: https://code.forgejo.org/actions/setup-go@v4 + with: + go-version: ">=1.20.0" + - run: | + git config --add safe.directory '*' + chown -R gitea:gitea . /go + - run: | + su gitea -c 'make deps-backend' + - run: | + su gitea -c 'make backend' + env: + TAGS: bindata + - run: | + su gitea -c 'make unit-test-coverage test-check' + timeout-minutes: 50 + env: + RACE_ENABLED: 'true' + TAGS: bindata + test-mysql: + runs-on: docker + needs: [lint-backend, checks-backend] + container: + image: codeberg.org/forgejo/test_env:main + services: + mysql8: + image: mysql:8 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: testgitea + ports: + - "3306:3306" + steps: + - uses: https://code.forgejo.org/actions/checkout@v3 + - uses: https://code.forgejo.org/actions/setup-go@v4 + with: + go-version: ">=1.20.0" + - run: | + git config --add safe.directory '*' + chown -R gitea:gitea . /go + - run: | + su gitea -c 'make deps-backend' + - run: | + su gitea -c 'make backend' + env: + TAGS: bindata + - run: | + su gitea -c 'make test-mysql8-migration test-mysql8' + timeout-minutes: 50 + env: + TAGS: bindata + USE_REPO_TEST_DIR: 1 + test-pgsql: + runs-on: docker + needs: [lint-backend, checks-backend] + container: + image: codeberg.org/forgejo/test_env:main + services: + pgsql: + image: postgres:15 + env: + POSTGRES_DB: test + POSTGRES_PASSWORD: postgres + ports: + - "5432:5432" + steps: + - uses: https://code.forgejo.org/actions/checkout@v3 + - uses: https://code.forgejo.org/actions/setup-go@v4 + with: + go-version: ">=1.20.0" + - run: | + git config --add safe.directory '*' + chown -R gitea:gitea . /go + - run: | + su gitea -c 'make deps-backend' + - run: | + su gitea -c 'make backend' + env: + TAGS: bindata + - run: | + su gitea -c 'make test-pgsql-migration test-pgsql' + timeout-minutes: 50 + env: + TAGS: bindata gogit + RACE_ENABLED: true + TEST_TAGS: gogit + USE_REPO_TEST_DIR: 1 + test-sqlite: + runs-on: docker + needs: [lint-backend, checks-backend] + container: + image: codeberg.org/forgejo/test_env:main + steps: + - uses: https://code.forgejo.org/actions/checkout@v3 + - uses: https://code.forgejo.org/actions/setup-go@v4 + with: + go-version: ">=1.20.0" + - run: | + git config --add safe.directory '*' + chown -R gitea:gitea . /go + - run: | + su gitea -c 'make deps-backend' + - run: | + su gitea -c 'make backend' + env: + TAGS: bindata gogit sqlite sqlite_unlock_notify + - run: | + su gitea -c 'make test-sqlite-migration test-sqlite' + timeout-minutes: 50 + env: + TAGS: bindata gogit sqlite sqlite_unlock_notify + RACE_ENABLED: true + TEST_TAGS: gogit sqlite sqlite_unlock_notify + USE_REPO_TEST_DIR: 1 diff --git a/.github/workflows/cron-licenses.yml b/.github/workflows/cron-licenses.yml deleted file mode 100644 index 4fa4016168..0000000000 --- a/.github/workflows/cron-licenses.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: cron-licenses - -on: - schedule: - - cron: "7 0 * * 1" # every Monday at 00:07 UTC - workflow_dispatch: - -jobs: - cron-licenses: - runs-on: ubuntu-latest - if: github.repository == 'go-gitea/gitea' - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: ">=1.20.1" - - run: make generate-license generate-gitignore - timeout-minutes: 40 - - name: push translations to repo - uses: appleboy/git-push-action@v0.0.2 - with: - author_email: "teabot@gitea.io" - author_name: GiteaBot - branch: main - commit: true - commit_message: "[skip ci] Updated licenses and gitignores" - remote: "git@github.com:go-gitea/gitea.git" - ssh_key: ${{ secrets.DEPLOY_KEY }} diff --git a/.github/workflows/cron-lock.yml b/.github/workflows/cron-lock.yml deleted file mode 100644 index 935f926cce..0000000000 --- a/.github/workflows/cron-lock.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: cron-lock - -on: - schedule: - - cron: "0 0 * * *" # every day at 00:00 UTC - workflow_dispatch: - -permissions: - issues: write - pull-requests: write - -concurrency: - group: lock - -jobs: - action: - runs-on: ubuntu-latest - if: github.repository == 'go-gitea/gitea' - steps: - - uses: dessant/lock-threads@v4 - with: - issue-inactive-days: 45 diff --git a/.github/workflows/cron-translations.yml b/.github/workflows/cron-translations.yml deleted file mode 100644 index 3f147c685d..0000000000 --- a/.github/workflows/cron-translations.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: cron-translations - -on: - schedule: - - cron: "7 0 * * *" # every day at 00:07 UTC - workflow_dispatch: - -jobs: - crowdin-pull: - runs-on: ubuntu-latest - if: github.repository == 'go-gitea/gitea' - steps: - - uses: actions/checkout@v3 - - name: download from crowdin - uses: docker://jonasfranz/crowdin - env: - CROWDIN_KEY: ${{ secrets.CROWDIN_KEY }} - PLUGIN_DOWNLOAD: true - PLUGIN_EXPORT_DIR: options/locale/ - PLUGIN_IGNORE_BRANCH: true - PLUGIN_PROJECT_IDENTIFIER: gitea - - name: update locales - run: ./build/update-locales.sh - - name: push translations to repo - uses: appleboy/git-push-action@v0.0.2 - with: - author_email: "teabot@gitea.io" - author_name: GiteaBot - branch: main - commit: true - commit_message: "[skip ci] Updated translations via Crowdin" - remote: "git@github.com:go-gitea/gitea.git" - ssh_key: ${{ secrets.DEPLOY_KEY }} - crowdin-push: - runs-on: ubuntu-latest - if: github.repository == 'go-gitea/gitea' - steps: - - uses: actions/checkout@v3 - - name: push translations to crowdin - uses: docker://jonasfranz/crowdin - env: - CROWDIN_KEY: ${{ secrets.CROWDIN_KEY }} - PLUGIN_UPLOAD: true - PLUGIN_EXPORT_DIR: options/locale/ - PLUGIN_IGNORE_BRANCH: true - PLUGIN_PROJECT_IDENTIFIER: gitea - PLUGIN_FILES: | - locale_en-US.ini: options/locale/locale_en-US.ini - PLUGIN_BRANCH: main diff --git a/.github/workflows/pull-compliance.yml b/.github/workflows/pull-compliance.yml deleted file mode 100644 index daee522c27..0000000000 --- a/.github/workflows/pull-compliance.yml +++ /dev/null @@ -1,140 +0,0 @@ -name: compliance - -on: - pull_request: - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - files-changed: - uses: ./.github/workflows/files-changed.yml - - lint-backend: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - with: - go-version: ">=1.20" - check-latest: true - - run: make deps-backend deps-tools - - run: make lint-backend - env: - TAGS: bindata sqlite sqlite_unlock_notify - - lint-go-windows: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - with: - go-version: ">=1.20" - check-latest: true - - run: make deps-backend deps-tools - - run: make lint-go-windows lint-go-vet - env: - TAGS: bindata sqlite sqlite_unlock_notify - GOOS: windows - GOARCH: amd64 - - lint-go-gogit: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - with: - go-version: ">=1.20" - check-latest: true - - run: make deps-backend deps-tools - - run: make lint-go - env: - TAGS: bindata gogit sqlite sqlite_unlock_notify - - checks-backend: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - with: - go-version: ">=1.20" - check-latest: true - - run: make deps-backend deps-tools - - run: make --always-make checks-backend # ensure the "go-licenses" make target runs - - frontend: - if: needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 20 - - run: make deps-frontend - - run: make lint-frontend - - run: make checks-frontend - - run: make frontend - - backend: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - with: - go-version: ">=1.20" - check-latest: true - # no frontend build here as backend should be able to build - # even without any frontend files - - run: make deps-backend deps-tools - - run: go build -o gitea_no_gcc # test if build succeeds without the sqlite tag - - name: build-backend-arm64 - run: make backend # test cross compile - env: - GOOS: linux - GOARCH: arm64 - TAGS: bindata gogit - - name: build-backend-windows - run: go build -o gitea_windows - env: - GOOS: windows - GOARCH: amd64 - TAGS: bindata gogit - - name: build-backend-386 - run: go build -o gitea_linux_386 # test if compatible with 32 bit - env: - GOOS: linux - GOARCH: 386 - - docs: - if: needs.files-changed.outputs.docs == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 20 - - run: make deps-frontend - - run: make lint-md - - run: make docs # test if build could succeed - - actions: - if: needs.files-changed.outputs.actions == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - - run: make lint-actions diff --git a/.github/workflows/pull-db-tests.yml b/.github/workflows/pull-db-tests.yml deleted file mode 100644 index 3b9768a74b..0000000000 --- a/.github/workflows/pull-db-tests.yml +++ /dev/null @@ -1,247 +0,0 @@ -name: db-tests - -on: - pull_request: - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - files-changed: - uses: ./.github/workflows/files-changed.yml - - test-pgsql: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - services: - pgsql: - image: postgres:15 - env: - POSTGRES_DB: test - POSTGRES_PASSWORD: postgres - ports: - - "5432:5432" - ldap: - image: gitea/test-openldap:latest - ports: - - "389:389" - - "636:636" - minio: - # as github actions doesn't support "entrypoint", we need to use a non-official image - # that has a custom entrypoint set to "minio server /data" - image: bitnami/minio:2021.3.17 - env: - MINIO_ACCESS_KEY: 123456 - MINIO_SECRET_KEY: 12345678 - ports: - - "9000:9000" - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - with: - go-version: ">=1.20.0" - - name: Add hosts to /etc/hosts - run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 pgsql ldap minio" | sudo tee -a /etc/hosts' - - run: make deps-backend - - run: make backend - env: - TAGS: bindata - - run: make test-pgsql-migration test-pgsql - timeout-minutes: 50 - env: - TAGS: bindata gogit - RACE_ENABLED: true - TEST_TAGS: gogit - TEST_LDAP: 1 - USE_REPO_TEST_DIR: 1 - - test-sqlite: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - with: - go-version: ">=1.20.0" - - run: make deps-backend - - run: make backend - env: - TAGS: bindata gogit sqlite sqlite_unlock_notify - - run: make test-sqlite-migration test-sqlite - timeout-minutes: 50 - env: - TAGS: bindata gogit sqlite sqlite_unlock_notify - RACE_ENABLED: true - TEST_TAGS: gogit sqlite sqlite_unlock_notify - USE_REPO_TEST_DIR: 1 - - test-unit: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - services: - mysql: - image: mysql:5.7 - env: - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: test - ports: - - "3306:3306" - elasticsearch: - image: elasticsearch:7.5.0 - env: - discovery.type: single-node - ports: - - "9200:9200" - smtpimap: - image: tabascoterrier/docker-imap-devel:latest - ports: - - "25:25" - - "143:143" - - "587:587" - - "993:993" - redis: - image: redis - options: >- # wait until redis has started - --health-cmd "redis-cli ping" - --health-interval 5s - --health-timeout 3s - --health-retries 10 - ports: - - 6379:6379 - minio: - image: bitnami/minio:2021.3.17 - env: - MINIO_ACCESS_KEY: 123456 - MINIO_SECRET_KEY: 12345678 - ports: - - "9000:9000" - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - with: - go-version: ">=1.20.0" - - name: Add hosts to /etc/hosts - run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mysql elasticsearch smtpimap" | sudo tee -a /etc/hosts' - - run: make deps-backend - - run: make backend - env: - TAGS: bindata - - name: unit-tests - run: make unit-test-coverage test-check - env: - TAGS: bindata - RACE_ENABLED: true - GITHUB_READ_TOKEN: ${{ secrets.GITHUB_READ_TOKEN }} - - name: unit-tests-gogit - run: make unit-test-coverage test-check - env: - TAGS: bindata gogit - RACE_ENABLED: true - GITHUB_READ_TOKEN: ${{ secrets.GITHUB_READ_TOKEN }} - - test-mysql5: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - services: - mysql: - image: mysql:5.7 - env: - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: test - ports: - - "3306:3306" - elasticsearch: - image: elasticsearch:7.5.0 - env: - discovery.type: single-node - ports: - - "9200:9200" - smtpimap: - image: tabascoterrier/docker-imap-devel:latest - ports: - - "25:25" - - "143:143" - - "587:587" - - "993:993" - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - with: - go-version: ">=1.20.0" - - name: Add hosts to /etc/hosts - run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mysql elasticsearch smtpimap" | sudo tee -a /etc/hosts' - - run: make deps-backend - - run: make backend - env: - TAGS: bindata - - name: run tests - run: make test-mysql-migration integration-test-coverage - env: - TAGS: bindata - RACE_ENABLED: true - USE_REPO_TEST_DIR: 1 - TEST_INDEXER_CODE_ES_URL: "http://elastic:changeme@elasticsearch:9200" - - test-mysql8: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - services: - mysql8: - image: mysql:8 - env: - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: testgitea - ports: - - "3306:3306" - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - with: - go-version: ">=1.20.0" - - name: Add hosts to /etc/hosts - run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mysql8" | sudo tee -a /etc/hosts' - - run: make deps-backend - - run: make backend - env: - TAGS: bindata - - run: make test-mysql8-migration test-mysql8 - timeout-minutes: 50 - env: - TAGS: bindata - USE_REPO_TEST_DIR: 1 - - test-mssql: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - services: - mssql: - image: mcr.microsoft.com/mssql/server:latest - env: - ACCEPT_EULA: Y - MSSQL_PID: Standard - SA_PASSWORD: MwantsaSecurePassword1 - ports: - - "1433:1433" - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - with: - go-version: ">=1.20.0" - - name: Add hosts to /etc/hosts - run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mssql" | sudo tee -a /etc/hosts' - - run: make deps-backend - - run: make backend - env: - TAGS: bindata - - run: make test-mssql-migration test-mssql - timeout-minutes: 50 - env: - TAGS: bindata - USE_REPO_TEST_DIR: 1 diff --git a/.github/workflows/pull-docker-dryrun.yml b/.github/workflows/pull-docker-dryrun.yml deleted file mode 100644 index 916de6b27d..0000000000 --- a/.github/workflows/pull-docker-dryrun.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: docker-dryrun - -on: - pull_request: - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - files-changed: - uses: ./.github/workflows/files-changed.yml - - docker-dryrun: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - steps: - - uses: docker/setup-buildx-action@v2 - - uses: docker/build-push-action@v4 - with: - push: false - tags: gitea/gitea:linux-amd64 diff --git a/.github/workflows/pull-e2e-tests.yml b/.github/workflows/pull-e2e-tests.yml deleted file mode 100644 index 6577cfd240..0000000000 --- a/.github/workflows/pull-e2e-tests.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: e2e-tests - -on: - pull_request: - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - files-changed: - uses: ./.github/workflows/files-changed.yml - - test-e2e: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true' - needs: files-changed - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 - with: - go-version: ">=1.20" - check-latest: true - - uses: actions/setup-node@v3 - with: - node-version: 20 - - run: make deps-frontend frontend deps-backend - - run: npx playwright install --with-deps - - run: make test-e2e-sqlite - timeout-minutes: 40 - env: - USE_REPO_TEST_DIR: 1