diff --git a/.github/ISSUE_TEMPLATE/developer-onboarding.md b/.github/ISSUE_TEMPLATE/developer-onboarding.md index 5dbcdb822..82c8c2c63 100644 --- a/.github/ISSUE_TEMPLATE/developer-onboarding.md +++ b/.github/ISSUE_TEMPLATE/developer-onboarding.md @@ -35,10 +35,10 @@ cf login -a api.fr.cloud.gov --sso - [ ] Setup [commit signing in Github](#setting-up-commit-signing) and with git locally. ### Steps for the onboarder -- [ ] Add the onboardee to cloud.gov org and relevant spaces as a SpaceDeveloper +- [ ] Add the onboardee to cloud.gov org (cisa-getgov-prototyping) and relevant spaces (unstable) as a SpaceDeveloper ```bash -cf set-space-role sandbox-gsa dotgov-poc SpaceDeveloper +cf set-space-role cisa-getgov-prototyping unstable SpaceDeveloper ``` - [ ] Add the onboardee to our login.gov sandbox team (`.gov registrar poc`) via the [dashboard](https://dashboard.int.identitysandbox.gov/) diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 1f5620cd3..5c1a68ac6 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -3,8 +3,7 @@ name: Build and deploy # This workflow runs on pushes to main (typically, # a merged pull request) and on pushes of tagged commits. -# Pushes to main will deploy to Unstable; tagged commits -# will deploy to Staging +# Pushes to main will deploy to Staging on: push: @@ -17,9 +16,9 @@ on: workflow_dispatch: jobs: - deploy-unstable: + deploy-staging: # if this job runs on a branch, we deduce that code - # has been pushed to main and should be deployed to unstable + # has been pushed to main and should be deployed to staging if: ${{ github.ref_type == 'branch' }} runs-on: ubuntu-latest steps: @@ -30,13 +29,8 @@ jobs: env: DEPLOY_NOW: thanks with: - cf_username: ${{ secrets.CF_USERNAME }} - cf_password: ${{ secrets.CF_PASSWORD }} - cf_org: sandbox-gsa - cf_space: dotgov-poc - push_arguments: "-f ops/manifests/manifest-unstable.yaml" - - # deploy-staging: - # # if this job runs on a tag, we deduce that code - # # has been tagged for release and should be deployed to staging - # if: ${{ github.ref_type == 'tag' }} + cf_username: ${{ secrets.CF_STAGING_USERNAME }} + cf_password: ${{ secrets.CF_STAGING_PASSWORD }} + cf_org: cisa-getgov-prototyping + cf_space: staging + push_arguments: "-f ops/manifests/manifest-staging.yaml" diff --git a/.github/workflows/migrate.yaml b/.github/workflows/migrate.yaml index 004352e48..a58bd30d4 100644 --- a/.github/workflows/migrate.yaml +++ b/.github/workflows/migrate.yaml @@ -3,7 +3,7 @@ name: Run Migrations # This workflow can be run from the CLI # gh workflow run migrate.yaml -f environment=sandbox # OR -# cf run-task getgov-unstable --wait \ +# cf run-task getgov-staging --wait \ # --command 'python manage.py migrate' --name migrate on: @@ -13,22 +13,19 @@ on: type: choice description: Where should we run migrations options: - - unstable - staging jobs: - migrate-unstable: - if: ${{ github.event.inputs.environment == 'unstable' }} + migrate-staging: + if: ${{ github.event.inputs.environment == 'staging' }} runs-on: ubuntu-latest steps: - - name: Run Django migrations for unstable + - name: Run Django migrations for staging uses: 18f/cg-deploy-action@main with: cf_username: ${{ secrets.CF_USERNAME }} cf_password: ${{ secrets.CF_PASSWORD }} - cf_org: sandbox-gsa - cf_space: dotgov-poc - full_command: "cf run-task getgov-unstable --wait --command 'python manage.py migrate' --name migrate" + cf_org: cisa-getgov-prototyping + cf_space: staging + full_command: "cf run-task getgov-staging --wait --command 'python manage.py migrate' --name migrate" - # migrate: - # if: ${{ github.event.inputs.environment == 'staging' }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c8df0c404..812c0bd1c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ docs/research/data/** static/ +public/ credentials* ### The usual garbage files ### @@ -148,3 +149,9 @@ cython_debug/ # Node node_modules + +# Mac +.DS_Store + +# Vim +*.swp diff --git a/docs/developer/README.md b/docs/developer/README.md index a7821e8a7..23d1948b3 100644 --- a/docs/developer/README.md +++ b/docs/developer/README.md @@ -75,3 +75,13 @@ docker-compose run pa11y npm run pa11y-ci The URLs that `pa11y-ci` will scan are configured in `src/.pa11yci`. When new views and pages are added, their URLs should also be added to that file. + +## USWDS and styling +We use the U.S. Web Design System (USWDS) for building and styling our applications. Additionally, we utilize the [uswds-compile tool](https://designsystem.digital.gov/documentation/getting-started/developers/phase-two-compile/) from USWDS to compile and package the static assets. +When you run `docker-compose up` the `node` service in the container will begin to watch for changes in the `registrar/assets` folder, and will recompile once any changes are made. +Within the `registrar/assets` folder, the `_theme` folder contains three files initially generated by `uswds-compile`: +1. `_uswds-theme-custom-styles` contains all the custom styles created for this application +2. `_uswds-theme` contains all the custom theme settings (e.g. primary colors, fonts, banner color, etc..) +3. `styles.css` a entry point or index for the styles, forwards all of the other style files used in the project (i.e. the USWDS source code, the settings, and all custom stylesheets). + +You can also compile the sass at any time using `npx gulp compile`. Similarly, you can copy over other static assets (images and javascript files), using `npx gulp copyAssets`. diff --git a/docs/operations/README.md b/docs/operations/README.md index 3e3d32481..437dba2c0 100644 --- a/docs/operations/README.md +++ b/docs/operations/README.md @@ -28,8 +28,24 @@ cf target -o -s ## Database -In sandbox, created with `cf create-service aws-rds micro-psql getgov-database`. +In sandbox, created with `cf create-service aws-rds micro-psql getgov-ENV-database`. Binding the database in `manifest-.json` automatically inserts the connection string into the environment as `DATABASE_URL`. -[Cloud.gov RDS documentation](https://cloud.gov/docs/services/relational-database/). \ No newline at end of file +[Cloud.gov RDS documentation](https://cloud.gov/docs/services/relational-database/). + +# Deploy + +We have two environments: `unstable` and `staging`. Developers can deploy locally to unstable whenever they want. However, only our CD service can deploy to `staging`, and it does so on every commit to `main`. This is to ensure that we have a "golden" environment to point to, and can still test things out in an unstable space. To deploy locally to `unstable`: + +```bash +cf target -o cisa-getgov-prototyping -s unstable +cf push getgov-unstable -f ops/manifests/manifest-unstable.yaml +cf run-task getgov-unstable --command 'python manage.py migrate' --name migrate +``` + + +## Serving static assets +We are using [WhiteNoise](http://whitenoise.evans.io/en/stable/index.html) plugin to serve our static assets on cloud.gov. This plugin is added to the `MIDDLEWARE` list in our apps `settings.py`. + +Note that it’s a good idea to run `collectstatic` locally or in the docker container before pushing files up to `unstable`. This is because `collectstatic` relies on timestamps when deciding to whether to overwrite the existing assets in `/public`. Due the way files are uploaded, the compiled css in the `/assets/css` folder on `unstable` will have a slightly earlier timestamp than the files in `/public/css`, and consequently running `collectstatic` on`unstable` will not update `public/css` as you may expect. diff --git a/docs/operations/runbooks/rotate_application_secrets.md b/docs/operations/runbooks/rotate_application_secrets.md index a82453d44..0c2045ebe 100644 --- a/docs/operations/runbooks/rotate_application_secrets.md +++ b/docs/operations/runbooks/rotate_application_secrets.md @@ -27,7 +27,7 @@ To rotate secrets, create a new `credentials-.json` file, upload it Example: ```bash -cf uups getgov-credentials -p credentials-unstable.json +cf cups getgov-credentials -p credentials-unstable.json cf restage getgov-unstable --strategy rolling ``` diff --git a/ops/manifests/manifest-staging.yaml b/ops/manifests/manifest-staging.yaml new file mode 100644 index 000000000..e474f8ba2 --- /dev/null +++ b/ops/manifests/manifest-staging.yaml @@ -0,0 +1,23 @@ +--- +applications: +- name: getgov-staging + buildpacks: + - python_buildpack + path: ../../src + instances: 1 + memory: 512M + stack: cflinuxfs3 + timeout: 180 + command: gunicorn registrar.config.wsgi -t 60 + health-check-type: http + health-check-http-endpoint: /health + env: + # Send stdout and stderr straight to the terminal without buffering + PYTHONUNBUFFERED: yup + # Tell Django where to find its configuration + DJANGO_SETTINGS_MODULE: registrar.config.settings + routes: + - route: getgov-staging.app.cloud.gov + services: + - getgov-credentials + - getgov-staging-database \ No newline at end of file diff --git a/ops/manifests/manifest-unstable.yaml b/ops/manifests/manifest-unstable.yaml index 976bd4425..4b523118c 100644 --- a/ops/manifests/manifest-unstable.yaml +++ b/ops/manifests/manifest-unstable.yaml @@ -8,7 +8,7 @@ applications: memory: 512M stack: cflinuxfs3 timeout: 180 - command: gunicorn registrar.config.wsgi -t 60 + command: ./run.sh health-check-type: http health-check-http-endpoint: /health env: @@ -20,4 +20,4 @@ applications: - route: getgov-unstable.app.cloud.gov services: - getgov-credentials - - getgov-database \ No newline at end of file + - getgov-unstable-database diff --git a/ops/scripts/rotate_cloud_secrets.sh b/ops/scripts/rotate_cloud_secrets.sh index 68f5371dc..ff1d05e27 100755 --- a/ops/scripts/rotate_cloud_secrets.sh +++ b/ops/scripts/rotate_cloud_secrets.sh @@ -1,11 +1,16 @@ # NOTE: This script does not work with cf v8. We recommend using cf v7 for all cloud.gov commands. if [ ! $(command -v gh) ] || [ ! $(command -v jq) ] || [ ! $(command -v cf) ]; then - echo "jq, cf, and gh packages must be installed. Please install via your preferred manager." - exit 1 + echo "jq, cf, and gh packages must be installed. Please install via your preferred manager." + exit 1 fi -cf spaces -read -p "Are you logged in to the dotgov-poc CF space above? (y/n) " -n 1 -r +if [ -z "$1" ]; then + echo 'Please specify a space to target (i.e. unstable, staging)' >&2 + exit 1 +fi + +cf target -o cisa-getgov-prototyping -s $1 +read -p "Are you logged in to the cisa-getgov-prototyping CF org above and targeting the correct space? (y/n) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]] then @@ -13,7 +18,7 @@ then fi gh auth status -read -p "Are you logged into a Github account with access to cisagov/dotgov? (y/n) " -n 1 -r +read -p "Are you logged into a Github account with access to cisagov/getgov? (y/n) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]] then @@ -21,6 +26,7 @@ then fi echo "Great, removing and replacing Github CD account..." +cf target -s $1 cf delete-service-key github-cd-account github-cd-key cf create-service-key github-cd-account github-cd-key cf service-key github-cd-account github-cd-key @@ -31,8 +37,9 @@ then exit 1 fi +upcase_space=$(printf "%s" "$1" | tr '[:lower:]' '[:upper:]') cf service-key github-cd-account github-cd-key | sed 1,2d | jq -r '[.username, .password]|@tsv' | while read -r username password; do - gh secret --repo cisagov/dotgov set CF_USERNAME --body $username - gh secret --repo cisagov/dotgov set CF_PASSWORD --body $password + gh secret --repo cisagov/getgov set CF_${upcase_space}_USERNAME --body $username + gh secret --repo cisagov/getgov set CF_${upcase_space}_PASSWORD --body $password done diff --git a/src/Pipfile b/src/Pipfile index 5bb43eaaf..0258dc930 100644 --- a/src/Pipfile +++ b/src/Pipfile @@ -11,6 +11,7 @@ django-csp = "*" environs = {extras=["django"]} gunicorn = "*" psycopg2-binary = "*" +whitenoise = "*" [dev-packages] django-debug-toolbar = "*" @@ -19,4 +20,4 @@ bandit = "*" black = "*" flake8 = "*" mypy = "*" -types-requests = "*" \ No newline at end of file +types-requests = "*" diff --git a/src/Pipfile.lock b/src/Pipfile.lock index ff6dfe7ab..4b9a11c9b 100644 --- a/src/Pipfile.lock +++ b/src/Pipfile.lock @@ -46,11 +46,11 @@ }, "django": { "hashes": [ - "sha256:031ccb717782f6af83a0063a1957686e87cb4581ea61b47b3e9addf60687989a", - "sha256:032f8a6fc7cf05ccd1214e4a2e21dfcd6a23b9d575c6573cacc8c67828dbe642" + "sha256:a153ffd5143bf26a877bfae2f4ec736ebd8924a46600ca089ad96b54a1d4e28e", + "sha256:acb21fac9275f9972d81c7caf5761a89ec3ea25fe74545dd26b8a48cb3a0203e" ], "index": "pypi", - "version": "==4.1" + "version": "==4.1.1" }, "django-allow-cidr": { "hashes": [ @@ -196,11 +196,11 @@ }, "python-dotenv": { "hashes": [ - "sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f", - "sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938" + "sha256:1684eb44636dd462b66c3ee016599815514527ad99965de77f43e0944634a7e5", + "sha256:b77d08274639e3d34145dfa6c7008e66df0f04b7be7a75fd0d5292c191d79045" ], - "markers": "python_version >= '3.5'", - "version": "==0.20.0" + "markers": "python_version >= '3.7'", + "version": "==0.21.0" }, "setuptools": { "hashes": [ @@ -225,6 +225,14 @@ ], "markers": "python_version >= '3.5'", "version": "==0.4.2" + }, + "whitenoise": { + "hashes": [ + "sha256:8e9c600a5c18bd17655ef668ad55b5edf6c24ce9bdca5bf607649ca4b1e8e2c2", + "sha256:8fa943c6d4cd9e27673b70c21a07b0aa120873901e099cd46cab40f7cc96d567" + ], + "index": "pypi", + "version": "==6.2.0" } }, "develop": { @@ -291,11 +299,11 @@ }, "django": { "hashes": [ - "sha256:031ccb717782f6af83a0063a1957686e87cb4581ea61b47b3e9addf60687989a", - "sha256:032f8a6fc7cf05ccd1214e4a2e21dfcd6a23b9d575c6573cacc8c67828dbe642" + "sha256:a153ffd5143bf26a877bfae2f4ec736ebd8924a46600ca089ad96b54a1d4e28e", + "sha256:acb21fac9275f9972d81c7caf5761a89ec3ea25fe74545dd26b8a48cb3a0203e" ], "index": "pypi", - "version": "==4.1" + "version": "==4.1.1" }, "django-debug-toolbar": { "hashes": [ diff --git a/src/docker-compose.yml b/src/docker-compose.yml index 6551d1519..bbd6f20d5 100644 --- a/src/docker-compose.yml +++ b/src/docker-compose.yml @@ -41,6 +41,15 @@ services: - POSTGRES_USER=user - POSTGRES_PASSWORD=feedabee + node: + image: node + volumes: + - .:/app + working_dir: /app + stdin_open: true + tty: true + command: ./run_node_watch.sh + pa11y: build: context: . diff --git a/src/gulpfile.js b/src/gulpfile.js new file mode 100644 index 000000000..e55705b22 --- /dev/null +++ b/src/gulpfile.js @@ -0,0 +1,35 @@ +/* gulpfile.js */ + +const uswds = require('@uswds/compile'); + +/** + * USWDS version + * Set the version of USWDS you're using (2 or 3) + */ + +uswds.settings.version = 3; + +/** + * Path settings + * Set as many as you need + */ + +const ASSETS_DIR = './registrar/assets/'; + +uswds.paths.dist.css = ASSETS_DIR + 'css'; +uswds.paths.dist.sass = ASSETS_DIR + 'sass'; +uswds.paths.dist.theme = ASSETS_DIR + 'sass/_theme'; +uswds.paths.dist.fonts = ASSETS_DIR + 'fonts'; +uswds.paths.dist.js = ASSETS_DIR + 'js'; +uswds.paths.dist.img = ASSETS_DIR + 'img'; + +/** + * Exports + * Add as many as you need + */ + +exports.init = uswds.init; +exports.compile = uswds.compile; +exports.watch = uswds.watch; +exports.copyAssets = uswds.copyAssets + diff --git a/src/package-lock.json b/src/package-lock.json index 450e9cf88..ad8c86936 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -1064,9 +1064,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001393", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001393.tgz", - "integrity": "sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA==", + "version": "1.0.30001399", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001399.tgz", + "integrity": "sha512-4vQ90tMKS+FkvuVWS5/QY1+d805ODxZiKFzsU8o/RsVJz49ZSRR8EjykLJbqhzdPgadbX6wB538wOzle3JniRA==", "dev": true, "funding": [ { @@ -1690,9 +1690,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.244", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.244.tgz", - "integrity": "sha512-E21saXLt2eTDaTxgUtiJtBUqanF9A32wZasAwDZ8gvrqXoxrBrbwtDCx7c/PQTLp81wj4X0OLDeoGQg7eMo3+w==", + "version": "1.4.248", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.248.tgz", + "integrity": "sha512-qShjzEYpa57NnhbW2K+g+Fl+eNoDvQ7I+2MRwWnU6Z6F0HhXekzsECCLv+y2OJUsRodjqoSfwHkIX42VUFtUzg==", "dev": true }, "node_modules/element-closest": { @@ -2030,9 +2030,9 @@ } }, "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -2405,9 +2405,9 @@ "dev": true }, "node_modules/get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "dependencies": { "function-bind": "^1.1.1", @@ -6597,9 +6597,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.7.tgz", - "integrity": "sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", + "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==", "dev": true, "funding": [ { @@ -7742,9 +7742,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001393", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001393.tgz", - "integrity": "sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA==", + "version": "1.0.30001399", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001399.tgz", + "integrity": "sha512-4vQ90tMKS+FkvuVWS5/QY1+d805ODxZiKFzsU8o/RsVJz49ZSRR8EjykLJbqhzdPgadbX6wB538wOzle3JniRA==", "dev": true }, "check-types": { @@ -8237,9 +8237,9 @@ } }, "electron-to-chromium": { - "version": "1.4.244", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.244.tgz", - "integrity": "sha512-E21saXLt2eTDaTxgUtiJtBUqanF9A32wZasAwDZ8gvrqXoxrBrbwtDCx7c/PQTLp81wj4X0OLDeoGQg7eMo3+w==", + "version": "1.4.248", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.248.tgz", + "integrity": "sha512-qShjzEYpa57NnhbW2K+g+Fl+eNoDvQ7I+2MRwWnU6Z6F0HhXekzsECCLv+y2OJUsRodjqoSfwHkIX42VUFtUzg==", "dev": true }, "element-closest": { @@ -8514,9 +8514,9 @@ } }, "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -8812,9 +8812,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -12042,9 +12042,9 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.7.tgz", - "integrity": "sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", + "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==", "dev": true, "requires": { "escalade": "^3.1.1", diff --git a/src/registrar/assets/img/registrar/dotgov_banner.png b/src/registrar/assets/img/registrar/dotgov_banner.png new file mode 100644 index 000000000..ae6fe75cb Binary files /dev/null and b/src/registrar/assets/img/registrar/dotgov_banner.png differ diff --git a/src/registrar/assets/sass/_theme/_uswds-theme-custom-styles.scss b/src/registrar/assets/sass/_theme/_uswds-theme-custom-styles.scss new file mode 100644 index 000000000..74ad72cad --- /dev/null +++ b/src/registrar/assets/sass/_theme/_uswds-theme-custom-styles.scss @@ -0,0 +1,28 @@ +/* +* * * * * ============================== +* * * * * ============================== +* * * * * ============================== +* * * * * ============================== +======================================== +======================================== +======================================== +---------------------------------------- +USWDS THEME CUSTOM STYLES +---------------------------------------- +!! Copy this file to your project's + sass root. Don't edit the version + in node_modules. +---------------------------------------- +Custom project SASS goes here. + +i.e. +@include u-padding-right('05'); +---------------------------------------- +*/ + +@use "uswds-core" as *; + +// Test custom style +p { + color: color('blue-10v'); +} diff --git a/src/registrar/assets/sass/_theme/_uswds-theme.scss b/src/registrar/assets/sass/_theme/_uswds-theme.scss new file mode 100644 index 000000000..f5d0724a6 --- /dev/null +++ b/src/registrar/assets/sass/_theme/_uswds-theme.scss @@ -0,0 +1,22 @@ +/* +---------------------------------------- +USWDS with settings overrides +---------------------------------------- +Uncomment the following lines and add a list of changed settings +in the form $setting: value, +---------------------------------------- +*/ + +// +// @use "uswds-core" with ( +// $setting: value, +// $setting: value +// ); +// +@use "uswds-core" with ( + $theme-banner-background-color: "ink", + $theme-banner-link-color: "primary-light", + $theme-banner-max-width: "none", + $theme-show-notifications: false, + $theme-hero-image: "../img/registrar/dotgov_banner.png" +) diff --git a/src/registrar/assets/sass/_theme/styles.scss b/src/registrar/assets/sass/_theme/styles.scss new file mode 100644 index 000000000..aef29a7f5 --- /dev/null +++ b/src/registrar/assets/sass/_theme/styles.scss @@ -0,0 +1,11 @@ +/*-------------------------------------------------- +--- USWDS Settings --------------------------------*/ +@forward "uswds-theme"; + +/*-------------------------------------------------- +--- USWDS Source ----------------------------------*/ +@forward "uswds"; + +/*-------------------------------------------------- +--- Custom Styles ---------------------------------*/ +@forward "uswds-theme-custom-styles"; diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py index ffca4489c..6eeab6740 100644 --- a/src/registrar/config/settings.py +++ b/src/registrar/config/settings.py @@ -88,6 +88,8 @@ INSTALLED_APPS = [ MIDDLEWARE = [ # django-allow-cidr: enable use of CIDR IP ranges in ALLOWED_HOSTS "allow_cidr.middleware.AllowCIDRMiddleware", + # serve static assets in production + "whitenoise.middleware.WhiteNoiseMiddleware", # provide security enhancements to the request/response cycle "django.middleware.security.SecurityMiddleware", # store and retrieve arbitrary data on a per-site-visitor basis @@ -130,7 +132,11 @@ WSGI_APPLICATION = "registrar.config.wsgi.application" # will place static files for deployment. # Do not use this directory for permanent storage - # it is for Django! -STATIC_ROOT = BASE_DIR / "static" +STATIC_ROOT = BASE_DIR / "public" + +STATICFILES_DIRS = [ + BASE_DIR / "assets", +] # TODO: decide on template engine and document in ADR TEMPLATES = [ @@ -388,6 +394,7 @@ SECURE_SSL_REDIRECT = True # web server configurations. ALLOWED_HOSTS = [ "getgov-unstable.app.cloud.gov", + "getgov-staging.app.cloud.gov", "get.gov", ] diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py index 16dbab1b5..613917001 100644 --- a/src/registrar/config/urls.py +++ b/src/registrar/config/urls.py @@ -8,9 +8,13 @@ from django.conf import settings from django.contrib import admin from django.urls import include, path -from registrar.views import health +from registrar.views import health, index -urlpatterns = [path("admin/", admin.site.urls), path("health/", health.health)] +urlpatterns = [ + path("admin/", admin.site.urls), + path("", index.index), + path("health/", health.health), +] if settings.DEBUG: import debug_toolbar diff --git a/src/registrar/templates/base.html b/src/registrar/templates/base.html new file mode 100644 index 000000000..3c303013d --- /dev/null +++ b/src/registrar/templates/base.html @@ -0,0 +1,215 @@ +{# keep this on the first line #} +{% load i18n static %} + + + + + + + {% block title %}{% endblock %} + {{ site.name }} + {% block extra_title %}{% endblock %} + + + {% block viewport_meta %} + + {% endblock %} + {% block extra_meta %}{% endblock extra_meta %} + + {# TO-DO: Determine if is desirable #} + + {# TO-DO: set defaults for these #} + + + + {% block css %} + + + {% endblock %} + + {% block canonical %} + + {% endblock %} + + + {% block feeds %}{% endblock %} + {% block extra_head %}{% endblock %} + + {# hat tip to USWDS... #} + + + + + + + + + + + + Skip to main content + +
+
+
+
+
+ U.S. flag +
+
+

+ An official website of the United States government +

+ +
+ +
+
+
+
+
+ +
+

+ Official websites use .gov
A + .gov website belongs to an official government + organization in the United States. +

+
+
+
+ +
+

+ Secure .gov websites use HTTPS
A + lock ( + + + + + ) or https:// means you’ve safely connected to + the .gov website. Share sensitive information only on official, + secure websites. +

+
+
+
+
+
+
+ + + {% block banner %} + + {% endblock banner %} + {% block usa_overlay %}
{% endblock %} +
+ {% block messages %} + {% if messages %} +
    + {% for message in messages %} + + {{ message }} + + {% endfor %} +
+ {% endif %} + {% endblock %} + + {% block section_nav %}{% endblock %} + +
+ {% block hero %}{% endblock %} + {% block content %}{% endblock %} +
+ +
{% block complementary %}{% endblock %}
+ + {% block content_bottom %}{% endblock %} +
+ +
+ {% block footer_nav %} + {% endblock %} + {% block footer %} +
+ +
+ {% endblock %} +
+ + + {% block init_js %}{% endblock %}{# useful for vars and other initializations #} + + {% block site_js %} + {% endblock %} + + {% block app_js %}{% endblock %} + + {% block extrascript %}{% endblock %} + + {# asynchronous analytics #} + + + diff --git a/src/registrar/templates/whoami.html b/src/registrar/templates/whoami.html new file mode 100644 index 000000000..9ad156c33 --- /dev/null +++ b/src/registrar/templates/whoami.html @@ -0,0 +1,18 @@ + +{% extends 'base.html' %} + +{% block title %} Hello {% endblock %} +{% block hero %} +
+
+
+

+ This is sample content. + This is only sample content. +

+

{{ name }} You'll want to replace it with content of your own.

+ +
+
+
+{% endblock %} diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py new file mode 100644 index 000000000..6fd69f61f --- /dev/null +++ b/src/registrar/views/index.py @@ -0,0 +1,6 @@ +from django.shortcuts import render + + +def index(request): + context = {"name": "World!"} + return render(request, "whoami.html", context) diff --git a/src/run.sh b/src/run.sh new file mode 100755 index 000000000..452469af4 --- /dev/null +++ b/src/run.sh @@ -0,0 +1,19 @@ +#/bin/bash + +set -o errexit +set -o pipefail + +# Only run migrations on the zeroth index when in a cloud.gov environment +if [[ -v CF_INSTANCE_INDEX && $CF_INSTANCE_INDEX == 0 ]] +then + python manage.py migrate --settings=registrar.config.settings --noinput +else + echo "Migrations did not run." + if [[ -v CF_INSTANCE_INDEX ]] + then + echo "CF Instance Index is ${CF_INSTANCE_INDEX}." + fi +fi + +python manage.py collectstatic --settings=registrar.config.settings --noinput +gunicorn registrar.config.wsgi -t 60 diff --git a/src/run_node_watch.sh b/src/run_node_watch.sh new file mode 100755 index 000000000..b793f229c --- /dev/null +++ b/src/run_node_watch.sh @@ -0,0 +1,15 @@ +#!/bin/bash +npm install +npm rebuild +dir=./registrar/assets +if [ -d "$dir" ] +then + echo "Compiling USWDS assets" + npx gulp copyAssets + npx gulp compile +else + echo "Initial USWDS assets build" + npx gulp init + npx gulp compile +fi +npx gulp watch