diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0320032305..1ebacfba4e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,3 +10,8 @@ updates: directory: '/' schedule: interval: monthly + + - package-ecosystem: 'docker' + directory: '/' + schedule: + interval: monthly diff --git a/.github/workflows/prod-build-deploy-azure.yml b/.github/workflows/prod-build-deploy-azure.yml index e638f8189e..a2f6a92c27 100644 --- a/.github/workflows/prod-build-deploy-azure.yml +++ b/.github/workflows/prod-build-deploy-azure.yml @@ -26,9 +26,14 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 env: - IMAGE_TAG_BASE: ${{ secrets.PROD_REGISTRY_SERVER }}/${{ github.repository }} + DOCKER_IMAGE: ${{ secrets.PROD_REGISTRY_SERVER }}/${{ github.repository }}:${{ github.sha }} steps: + - name: 'Az CLI login' + uses: azure/login@66d2e78565ab7af265d2b627085bc34c73ce6abb + with: + creds: ${{ secrets.PROD_AZURE_CREDENTIALS }} + - name: 'Docker login' uses: azure/docker-login@81744f9799e7eaa418697cb168452a2882ae844a with: @@ -68,10 +73,65 @@ jobs: context: . push: true target: 'production_early_access' - tags: ${{ env.IMAGE_TAG_BASE }}:${{ github.sha }}, ${{ env.IMAGE_TAG_BASE }}:production + tags: ${{ env.DOCKER_IMAGE }} cache-from: type=gha cache-to: type=gha,mode=max + - name: 'Update docker-compose.prod.yaml template file' + run: | + sed 's|#{IMAGE}#|${{ env.DOCKER_IMAGE }}|g' docker-compose.prod.tmpl.yaml > docker-compose.prod.yaml + + - name: 'Apply updated docker-compose.prod.yaml config to preview slot' + run: | + az webapp config container set --multicontainer-config-type COMPOSE --multicontainer-config-file docker-compose.prod.yaml --slot preview -n ghdocs-prod -g docs-prod + + # Watch preview slot instances to see when all the instances are ready + - name: Check that preview slot is ready + uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d + env: + CHECK_INTERVAL: 10000 + with: + script: | + const { execSync } = require('child_process') + + const getStatesForSlot = (slot) => { + return JSON.parse( + execSync( + `az webapp list-instances --slot ${slot} --query "[].state" -n ghdocs-prod -g docs-prod`, + { encoding: 'utf8' } + ) + ) + } + + let hasStopped = false + const waitDuration = parseInt(process.env.CHECK_INTERVAL, 10) || 10000 + async function doCheck() { + const states = getStatesForSlot('preview') + console.log(`Instance states:`, states) + + // We must wait until at-least 1 instance has STOPPED to know we're looking at the "next" deployment and not the "previous" one + // That way we don't immediately succeed just because all the previous instances were READY + if (!hasStopped) { + hasStopped = states.some((s) => s === 'STOPPED') + } + + const isAllReady = states.every((s) => s === 'READY') + + if (hasStopped && isAllReady) { + process.exit(0) // success + } + + console.log(`checking again in ${waitDuration}ms`) + setTimeout(doCheck, waitDuration) + } + + doCheck() + + # TODO - make a request to verify the preview app version aligns with *this* github action workflow commit sha + - name: 'Swap preview slot to production' + run: | + az webapp deployment slot swap --slot preview --target-slot production -n ghdocs-prod -g docs-prod + # TODO - enable this when we disable the other production deploy # - name: Purge Fastly edge cache # env: diff --git a/.github/workflows/staging-build-and-deploy-azure.yml b/.github/workflows/staging-build-and-deploy-azure.yml new file mode 100644 index 0000000000..985437ae76 --- /dev/null +++ b/.github/workflows/staging-build-and-deploy-azure.yml @@ -0,0 +1,118 @@ +name: Staging - Azure Deploy App Service + +# **What it does**: Build and deploy staging PRs to Azure +# **Why we have it**: It's our new staging deployment mechanism, only applicable to docs-internal +# **Who does it impact**: All contributors. + +# This whole workflow is only guaranteed to be secure in the *private +# repo* and because we repo-sync these files over the to the public one, +# IT'S IMPORTANT THAT THIS WORKFLOW IS ONLY ENABLED IN docs-internal! + +on: + # The advantage of 'pull_request' over 'pull_request_target' is that we + # can make changes to this file and test them in a pull request, instead + # of relying on landing it in 'main' first. + # From a security point of view, its arguably safer this way because + # unlike 'pull_request_target', these only have secrets if the pull + # request creator has permission to access secrets. + pull_request: + workflow_dispatch: + +permissions: + contents: read + deployments: write + +# This allows one deploy workflow to interrupt another +concurrency: + group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label }}' + cancel-in-progress: true + +jobs: + build-and-deploy: + if: ${{ github.repository == 'github/docs-internal' }} + name: Build and deploy image to staging App Service + runs-on: ubuntu-latest + timeout-minutes: 15 + environment: + name: staging-pr-${{ github.event.number }} + url: ${{ steps.deploy.outputs.defaultHostName }} + env: + GITHUB_EVENT_NUMBER: ${{ github.event.number }} + NONPROD_REGISTRY_USERNAME: ghdocs + # Image tag is unique to each workflow run so that it always triggers a new deployment + DOCKER_IMAGE: ${{ secrets.NONPROD_REGISTRY_SERVER }}/${{ github.repository }}/pr-${{ github.event.number }}:${{ github.event.pull_request.head.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + + steps: + - name: 'Set env vars' + id: vars + run: | + REPO_NAME=${GITHUB_REPOSITORY#*\/} + echo "REPO_NAME=${REPO_NAME}" >> $GITHUB_ENV + echo "APP_NAME=gh${REPO_NAME}-staging-${GITHUB_EVENT_NUMBER}" >> $GITHUB_ENV + + - name: 'Az CLI login' + uses: azure/login@66d2e78565ab7af265d2b627085bc34c73ce6abb + with: + creds: ${{ secrets.NONPROD_AZURE_CREDENTIALS }} + + - name: 'Docker login' + uses: azure/docker-login@81744f9799e7eaa418697cb168452a2882ae844a + with: + login-server: ${{ secrets.NONPROD_REGISTRY_SERVER }} + username: ${{ env.NONPROD_REGISTRY_USERNAME }} + password: ${{ secrets.NONPROD_REGISTRY_PASSWORD }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@94ab11c41e45d028884a99163086648e898eed25 + + - name: Check out repo + uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 + with: + ref: ${{ github.event.pull_request.head.sha }} + # To prevent issues with cloning early access content later + persist-credentials: 'false' + lfs: 'true' + + - name: Check out LFS objects + run: git lfs checkout + + - name: Setup node + uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458 + with: + node-version: 16.13.x + cache: npm + + - if: ${{ github.repository == 'github/docs-internal' }} + name: Clone early access + env: + DOCUBOT_REPO_PAT: ${{ secrets.DOCUBOT_REPO_PAT }} + GIT_BRANCH: ${{ github.event.pull_request.head.sha }} + run: npm install dotenv && node script/early-access/clone-for-build.js + + - name: 'Build and push image' + uses: docker/build-push-action@a66e35b9cbcf4ad0ea91ffcaf7bbad63ad9e0229 + with: + context: . + push: true + target: ${{ fromJSON('["production", "production_early_access"]')[github.repository == 'github/docs-internal'] }} + tags: ${{ env.DOCKER_IMAGE }} + cache-from: type=gha + cache-to: type=gha,mode=max + + # Deploy ARM template is idempotent + # Note: once the resources exist the image tag must change for a new deployment to occur (the image tag includes workflow run number, run attempt, as well as sha) + - name: Run ARM deploy + id: deploy + uses: azure/arm-deploy@841b12551939c88af8f6df767c24c38a5620fd0d + with: + resourceGroupName: docs-nonprod + subscriptionId: ${{ secrets.NONPROD_SUBSCRIPTION_ID }} + template: ./staging-azure-deploy-template.json + parameters: appName="${{ env.APP_NAME }}" + location="East US" + linuxFxVersion="DOCKER|${{ env.DOCKER_IMAGE }}" + dockerRegistryUrl="https://${{ secrets.NONPROD_REGISTRY_SERVER }}" + dockerRegistryUsername="${{ env.NONPROD_REGISTRY_USERNAME }}" + dockerRegistryPassword="${{ secrets.NONPROD_REGISTRY_PASSWORD }}" + + - run: echo ${{ steps.deploy.outputs.defaultHostName }} diff --git a/.github/workflows/staging-build-and-deploy-pr.yml b/.github/workflows/staging-build-and-deploy-pr.yml index 7554dfd644..c94d36ef03 100644 --- a/.github/workflows/staging-build-and-deploy-pr.yml +++ b/.github/workflows/staging-build-and-deploy-pr.yml @@ -133,7 +133,11 @@ jobs: # Delete all the big search indexes that are NOT English (`*-en-*`) pushd lib/search/indexes - ls | grep -v '\-en\-' | xargs rm + echo "BEFORE...." + ls -l + ls | grep -ve '\-en\b' | xargs rm + echo "AFTER...." + ls -l popd # Note! Some day it would be nice to be able to delete diff --git a/.github/workflows/staging-undeploy-azure.yml b/.github/workflows/staging-undeploy-azure.yml new file mode 100644 index 0000000000..3b4f9a8efb --- /dev/null +++ b/.github/workflows/staging-undeploy-azure.yml @@ -0,0 +1,50 @@ +name: Staging - Undeploy Azure PR + +# **What it does**: To undeploy PRs from Azure staging environment, i.e. destroy the App and associated resources. +# **Why we have it**: To save money spent on deployments for closed PRs. +# **Who does it impact**: All contributors. + +on: + pull_request: + types: + - closed + - locked + +jobs: + undeploy: + name: Undeploy + runs-on: ubuntu-latest + timeout-minutes: 5 + env: + GITHUB_EVENT_NUMBER: ${{ github.event.number }} + IMAGE_REPO: ${{ github.repository }}/pr-${{ github.event.number }} + + steps: + - name: 'Set env vars' + id: vars + run: | + REPO_NAME=${GITHUB_REPOSITORY#*\/} + echo "APP_NAME=gh${REPO_NAME}-staging-${GITHUB_EVENT_NUMBER}" >> $GITHUB_ENV + + - name: 'Az CLI login' + uses: azure/login@66d2e78565ab7af265d2b627085bc34c73ce6abb + with: + creds: ${{ secrets.NONPROD_AZURE_CREDENTIALS }} + + # Delete web app (which will also delete the App Service plan) + # This will succeed even if the app doesn't exist / has already been deleted + - name: 'Delete App Service App (which will also delete the App Service plan)' + run: | + az webapp delete -n $APP_NAME -g docs-nonprod + + # Untag all images under this PR's container registry repo - the container registry will automatically remove untagged images. + # This will fail if the IMAGE_REPO doesn't exist, but we don't care + - name: 'Untag all docker images for this PR' + run: | + az acr repository delete -n ghdocs --repository ${{ env.IMAGE_REPO }} -y || true + + # Remove all deployments from this environment and remove the environment + - uses: strumwolf/delete-deployment-environment@45c821e46baa405e25410700fe2e9643929706a0 + with: + token: ${{ secrets.DOCUBOT_REPO_PAT }} + environment: staging-pr-${{ github.event.number }} diff --git a/.github/workflows/workflow-lint.yml b/.github/workflows/workflow-lint.yml index a62dc5b23e..a0eaf2de10 100644 --- a/.github/workflows/workflow-lint.yml +++ b/.github/workflows/workflow-lint.yml @@ -30,4 +30,4 @@ jobs: - name: Run linter uses: cschleiden/actions-linter@caffd707beda4fc6083926a3dff48444bc7c24aa with: - workflows: '[".github/workflows/*.yml", ".github/workflows/*.yaml", "!.github/workflows/remove-from-fr-board.yaml", "!.github/workflows/staging-deploy-pr.yml", "!.github/workflows/triage-issue-comments.yml"]' + workflows: '[".github/workflows/*.yml", ".github/workflows/*.yaml", "!.github/workflows/remove-from-fr-board.yaml", "!.github/workflows/staging-deploy-pr.yml", "!.github/workflows/triage-issue-comments.yml", "!.github/workflows/staging-build-and-deploy-azure.yml"]' diff --git a/Dockerfile b/Dockerfile index fdabfa8c11..eb58794595 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,11 +5,15 @@ # -------------------------------------------------------------------------------- # BASE IMAGE # -------------------------------------------------------------------------------- -FROM node:16-alpine as base +FROM node:16.13.2-alpine@sha256:f21f35732964a96306a84a8c4b5a829f6d3a0c5163237ff4b6b8b34f8d70064b as base -RUN apk add --no-cache make g++ git +# This directory is owned by the node user +ARG APP_HOME=/home/node/app -WORKDIR /usr/src/docs +# Make sure we don't run anything as the root user +USER node + +WORKDIR $APP_HOME # --------------- @@ -17,8 +21,8 @@ WORKDIR /usr/src/docs # --------------- FROM base as all_deps -COPY .npmrc ./ -COPY package*.json ./ +COPY --chown=node:node .npmrc ./ +COPY --chown=node:node package*.json ./ RUN npm ci @@ -59,22 +63,13 @@ RUN npm run build # MAIN IMAGE # -------------------------------------------------------------------------------- -FROM node:16-alpine as production - -# Let's make our home -WORKDIR /usr/src/docs - -# Ensure our node user owns the directory we're using -RUN chown node:node /usr/src/docs -R - -# This should be our normal running user -USER node +FROM base as production # Copy just our prod dependencies -COPY --chown=node:node --from=prod_deps /usr/src/docs/node_modules /usr/src/docs/node_modules +COPY --chown=node:node --from=prod_deps $APP_HOME/node_modules $APP_HOME/node_modules # Copy our front-end code -COPY --chown=node:node --from=builder /usr/src/docs/.next /usr/src/docs/.next +COPY --chown=node:node --from=builder $APP_HOME/.next $APP_HOME/.next # We should always be running in production mode ENV NODE_ENV production diff --git a/assets/images/azure/azure-resources-search.png b/assets/images/azure/azure-resources-search.png new file mode 100644 index 0000000000..093792539a Binary files /dev/null and b/assets/images/azure/azure-resources-search.png differ diff --git a/assets/images/azure/azure-storage-containers.png b/assets/images/azure/azure-storage-containers.png new file mode 100644 index 0000000000..96059de04b Binary files /dev/null and b/assets/images/azure/azure-storage-containers.png differ diff --git a/assets/images/azure/azure-storage-permissions.png b/assets/images/azure/azure-storage-permissions.png new file mode 100644 index 0000000000..040479bdaa Binary files /dev/null and b/assets/images/azure/azure-storage-permissions.png differ diff --git a/assets/images/azure/azure-storage-shared-access-tokens.png b/assets/images/azure/azure-storage-shared-access-tokens.png new file mode 100644 index 0000000000..89a7a206de Binary files /dev/null and b/assets/images/azure/azure-storage-shared-access-tokens.png differ diff --git a/assets/images/enterprise/3.4/actions-access-settings.png b/assets/images/enterprise/3.4/actions-access-settings.png new file mode 100644 index 0000000000..752690015f Binary files /dev/null and b/assets/images/enterprise/3.4/actions-access-settings.png differ diff --git a/assets/images/help/enterprises/audit-stream-add-azureblob.png b/assets/images/help/enterprises/audit-stream-add-azureblob.png new file mode 100644 index 0000000000..21f4bf0cdf Binary files /dev/null and b/assets/images/help/enterprises/audit-stream-add-azureblob.png differ diff --git a/assets/images/help/enterprises/audit-stream-choice-azure.png b/assets/images/help/enterprises/audit-stream-choice-azure.png index 1f632f1db2..206d236942 100644 Binary files a/assets/images/help/enterprises/audit-stream-choice-azure.png and b/assets/images/help/enterprises/audit-stream-choice-azure.png differ diff --git a/assets/images/help/enterprises/audit-stream-choice-azureblob.png b/assets/images/help/enterprises/audit-stream-choice-azureblob.png new file mode 100644 index 0000000000..d7d08c51d4 Binary files /dev/null and b/assets/images/help/enterprises/audit-stream-choice-azureblob.png differ diff --git a/assets/images/help/enterprises/audit-stream-choice-google-cloud-storage.png b/assets/images/help/enterprises/audit-stream-choice-google-cloud-storage.png index 5fab644d54..036ebc0383 100644 Binary files a/assets/images/help/enterprises/audit-stream-choice-google-cloud-storage.png and b/assets/images/help/enterprises/audit-stream-choice-google-cloud-storage.png differ diff --git a/assets/images/help/enterprises/audit-stream-choice-s3.png b/assets/images/help/enterprises/audit-stream-choice-s3.png index a77a643924..0b0d6e3107 100644 Binary files a/assets/images/help/enterprises/audit-stream-choice-s3.png and b/assets/images/help/enterprises/audit-stream-choice-s3.png differ diff --git a/assets/images/help/enterprises/audit-stream-choice-splunk.png b/assets/images/help/enterprises/audit-stream-choice-splunk.png index 60fdab62a2..69708a399b 100644 Binary files a/assets/images/help/enterprises/audit-stream-choice-splunk.png and b/assets/images/help/enterprises/audit-stream-choice-splunk.png differ diff --git a/assets/images/help/images/workflow-dispatch-inputs.png b/assets/images/help/images/workflow-dispatch-inputs.png new file mode 100644 index 0000000000..93e0ef4cc5 Binary files /dev/null and b/assets/images/help/images/workflow-dispatch-inputs.png differ diff --git a/assets/images/help/repository/actions-general-tab.png b/assets/images/help/repository/actions-general-tab.png new file mode 100644 index 0000000000..52d7c24fd1 Binary files /dev/null and b/assets/images/help/repository/actions-general-tab.png differ diff --git a/assets/images/help/saml/okta-add-application.png b/assets/images/help/saml/okta-add-application.png deleted file mode 100644 index cb7438e952..0000000000 Binary files a/assets/images/help/saml/okta-add-application.png and /dev/null differ diff --git a/assets/images/help/saml/okta-add-ghec-application.png b/assets/images/help/saml/okta-add-ghec-application.png deleted file mode 100644 index a5632b64bf..0000000000 Binary files a/assets/images/help/saml/okta-add-ghec-application.png and /dev/null differ diff --git a/assets/images/help/saml/okta-admin-button.png b/assets/images/help/saml/okta-admin-button.png deleted file mode 100644 index 0746f748bf..0000000000 Binary files a/assets/images/help/saml/okta-admin-button.png and /dev/null differ diff --git a/assets/images/help/saml/okta-application-label.png b/assets/images/help/saml/okta-application-label.png deleted file mode 100644 index d596c23dcb..0000000000 Binary files a/assets/images/help/saml/okta-application-label.png and /dev/null differ diff --git a/assets/images/help/saml/okta-applications.png b/assets/images/help/saml/okta-applications.png deleted file mode 100644 index 3abdbe83df..0000000000 Binary files a/assets/images/help/saml/okta-applications.png and /dev/null differ diff --git a/assets/images/help/saml/okta-authenticate-with-ghec-organization.png b/assets/images/help/saml/okta-authenticate-with-ghec-organization.png deleted file mode 100644 index 557ff4860e..0000000000 Binary files a/assets/images/help/saml/okta-authenticate-with-ghec-organization.png and /dev/null differ diff --git a/assets/images/help/saml/okta-configure-api-integration.png b/assets/images/help/saml/okta-configure-api-integration.png deleted file mode 100644 index 27b80d7125..0000000000 Binary files a/assets/images/help/saml/okta-configure-api-integration.png and /dev/null differ diff --git a/assets/images/help/saml/okta-enable-api-integration.png b/assets/images/help/saml/okta-enable-api-integration.png deleted file mode 100644 index ab4a9ea7cf..0000000000 Binary files a/assets/images/help/saml/okta-enable-api-integration.png and /dev/null differ diff --git a/assets/images/help/saml/okta-github-enterprises.png b/assets/images/help/saml/okta-github-enterprises.png deleted file mode 100644 index 2f0edf4e5d..0000000000 Binary files a/assets/images/help/saml/okta-github-enterprises.png and /dev/null differ diff --git a/assets/images/help/saml/okta-github-organization-name.png b/assets/images/help/saml/okta-github-organization-name.png deleted file mode 100644 index e7d5839f31..0000000000 Binary files a/assets/images/help/saml/okta-github-organization-name.png and /dev/null differ diff --git a/assets/images/help/saml/okta-provisioning-enable-create-users.png b/assets/images/help/saml/okta-provisioning-enable-create-users.png deleted file mode 100644 index 5c8fd0cf21..0000000000 Binary files a/assets/images/help/saml/okta-provisioning-enable-create-users.png and /dev/null differ diff --git a/assets/images/help/saml/okta-provisioning-enable-deactivate-users.png b/assets/images/help/saml/okta-provisioning-enable-deactivate-users.png deleted file mode 100644 index 83dcc5c3be..0000000000 Binary files a/assets/images/help/saml/okta-provisioning-enable-deactivate-users.png and /dev/null differ diff --git a/assets/images/help/saml/okta-provisioning-enable-options.png b/assets/images/help/saml/okta-provisioning-enable-options.png new file mode 100644 index 0000000000..114532a138 Binary files /dev/null and b/assets/images/help/saml/okta-provisioning-enable-options.png differ diff --git a/assets/images/help/saml/okta-provisioning-enable-update-user-attributes.png b/assets/images/help/saml/okta-provisioning-enable-update-user-attributes.png deleted file mode 100644 index a1ef0384b9..0000000000 Binary files a/assets/images/help/saml/okta-provisioning-enable-update-user-attributes.png and /dev/null differ diff --git a/assets/images/help/saml/okta-provisioning-save.png b/assets/images/help/saml/okta-provisioning-save.png deleted file mode 100644 index 8c65117baf..0000000000 Binary files a/assets/images/help/saml/okta-provisioning-save.png and /dev/null differ diff --git a/assets/images/help/saml/okta-provisioning-tab-save.png b/assets/images/help/saml/okta-provisioning-tab-save.png deleted file mode 100644 index 8c36e4b621..0000000000 Binary files a/assets/images/help/saml/okta-provisioning-tab-save.png and /dev/null differ diff --git a/assets/images/help/saml/okta-provisioning-tab.png b/assets/images/help/saml/okta-provisioning-tab.png index d5d76dcdd5..206b128a0e 100644 Binary files a/assets/images/help/saml/okta-provisioning-tab.png and b/assets/images/help/saml/okta-provisioning-tab.png differ diff --git a/assets/images/help/saml/okta-provisioning-to-app-edit-button.png b/assets/images/help/saml/okta-provisioning-to-app-edit-button.png index bfd957fe4f..9ec796059d 100644 Binary files a/assets/images/help/saml/okta-provisioning-to-app-edit-button.png and b/assets/images/help/saml/okta-provisioning-to-app-edit-button.png differ diff --git a/assets/images/help/saml/okta-scim-integration-authorize-oktaoan.png b/assets/images/help/saml/okta-scim-integration-authorize-oktaoan.png deleted file mode 100644 index ebb2dd9834..0000000000 Binary files a/assets/images/help/saml/okta-scim-integration-authorize-oktaoan.png and /dev/null differ diff --git a/assets/images/help/saml/okta-search-for-an-application.png b/assets/images/help/saml/okta-search-for-an-application.png deleted file mode 100644 index c0c9205bef..0000000000 Binary files a/assets/images/help/saml/okta-search-for-an-application.png and /dev/null differ diff --git a/assets/images/help/saml/okta-sign-on-tab.png b/assets/images/help/saml/okta-sign-on-tab.png index 35f6351647..e907d72d14 100644 Binary files a/assets/images/help/saml/okta-sign-on-tab.png and b/assets/images/help/saml/okta-sign-on-tab.png differ diff --git a/assets/images/help/saml/okta-view-setup-instructions.png b/assets/images/help/saml/okta-view-setup-instructions.png deleted file mode 100644 index 52617c042f..0000000000 Binary files a/assets/images/help/saml/okta-view-setup-instructions.png and /dev/null differ diff --git a/assets/images/help/settings/actions-access-settings.png b/assets/images/help/settings/actions-access-settings.png index 752690015f..e88371dcaa 100644 Binary files a/assets/images/help/settings/actions-access-settings.png and b/assets/images/help/settings/actions-access-settings.png differ diff --git a/components/DefaultLayout.tsx b/components/DefaultLayout.tsx index e7e09e5266..bbb1bbb350 100644 --- a/components/DefaultLayout.tsx +++ b/components/DefaultLayout.tsx @@ -81,23 +81,27 @@ export const DefaultLayout = (props: Props) => { )} - + + Skip to main content + - -
+
- - +
+ + - {props.children} - - - - -
+ {props.children} +
+ + ) } diff --git a/components/Search.tsx b/components/Search.tsx index 3f6d0adc70..662ff49e76 100644 --- a/components/Search.tsx +++ b/components/Search.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef, ReactNode, RefObject } from 'react' import { useRouter } from 'next/router' import useSWR from 'swr' import cx from 'classnames' -import { ActionList, DropdownMenu, Label, Overlay } from '@primer/components' +import { ActionList, DropdownMenu, Flash, Label, Overlay } from '@primer/components' import { ItemInput } from '@primer/components/lib/ActionList/List' import { useTranslation } from 'components/hooks/useTranslation' @@ -176,20 +176,28 @@ export function Search({ 'pt-9 color-bg-default color-shadow-medium position-absolute top-0 right-0', styles.resultsContainer, isHeaderSearch && styles.resultsContainerHeader, - query ? 'd-block' : 'd-none', - query && styles.resultsContainerOpen + query || searchError ? 'd-block' : 'd-none', + (query || searchError) && styles.resultsContainerOpen )} > - + {searchError ? ( + + ) : ( + + )} {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
(value: T, delay?: number): [T, (value: T) => void] { return [debouncedValue, setDebouncedValue] } +function ShowSearchError({ + error, + isHeaderSearch, + isMobileSearch, +}: { + error: Error + isHeaderSearch: boolean + isMobileSearch: boolean +}) { + const { t } = useTranslation('search') + return ( + +

{t('search_error')}

+ {process.env.NODE_ENV === 'development' && ( +

+ + {error.toString()} + +

+ )} +
+ ) +} + function ShowSearchResults({ anchorRef, isHeaderSearch, diff --git a/components/guides/LearningTrack.module.scss b/components/guides/LearningTrack.module.scss index 006c85fee9..9aa8ef1c26 100644 --- a/components/guides/LearningTrack.module.scss +++ b/components/guides/LearningTrack.module.scss @@ -2,6 +2,10 @@ background: linear-gradient(to top, var(--color-canvas-default), transparent); } +.removeHoverEvents { + pointer-events: none; +} + /* Because of the sticky header */ .hashAnchor { &:target { diff --git a/components/guides/LearningTrack.tsx b/components/guides/LearningTrack.tsx index 70bd056e99..63eaa61262 100644 --- a/components/guides/LearningTrack.tsx +++ b/components/guides/LearningTrack.tsx @@ -2,7 +2,7 @@ import cx from 'classnames' import { useTranslation } from 'components/hooks/useTranslation' import { ArrowRightIcon } from '@primer/octicons-react' import { ActionList } from '@primer/components' -import { useEffect, useRef, useState } from 'react' +import { useState } from 'react' import { FeaturedTrack } from 'components/context/ProductGuidesContext' import { TruncateLines } from 'components/ui/TruncateLines' import slugger from 'github-slugger' @@ -17,15 +17,10 @@ export const LearningTrack = ({ track }: Props) => { const [numVisible, setNumVisible] = useState(DEFAULT_VISIBLE_GUIDES) const { t } = useTranslation('product_guides') const slug = track?.title ? slugger.slug(track?.title) : '' - const listRef = useRef(null) const showAll = () => { setNumVisible(track?.guides?.length || 0) } - useEffect(() => { - if (listRef.current) listRef.current.focus() - }) - return (
@@ -62,7 +57,6 @@ export const LearningTrack = ({ track }: Props) => { return { renderItem: () => ( { >
)} - {(track?.guides?.length || 0) > numVisible ? ( + { - ) : ( -
- )} + }
) diff --git a/components/landing/GuideCards.tsx b/components/landing/GuideCards.tsx index 59f0ebc183..a74d3acce4 100644 --- a/components/landing/GuideCards.tsx +++ b/components/landing/GuideCards.tsx @@ -20,10 +20,12 @@ export const GuideCards = () => { return (
-
- {(featuredLinks.guideCards || []).map((guide) => { - return - })} +
+
    + {(featuredLinks.guideCards || []).map((guide) => { + return + })} +
{!currentCategory && hasGuidesPage && ( diff --git a/components/page-footer/SmallFooter.tsx b/components/page-footer/SmallFooter.tsx index 9e6d90c295..cd3ecae758 100644 --- a/components/page-footer/SmallFooter.tsx +++ b/components/page-footer/SmallFooter.tsx @@ -7,7 +7,7 @@ export const SmallFooter = () => { const router = useRouter() const { t } = useTranslation('footer') return ( - +
) } diff --git a/components/page-footer/Survey.module.scss b/components/page-footer/Survey.module.scss new file mode 100644 index 0000000000..df1833bc25 --- /dev/null +++ b/components/page-footer/Survey.module.scss @@ -0,0 +1,15 @@ +.visuallyHidden { + opacity: 0; + margin: -0.4em; +} + +.customRadio + label:before { + content: "X"; + color: transparent; + margin: 0px -33px 0px -17px; + padding: 7px 20px 7px 20px; +} + +.customRadio:focus + label:before { + outline: 1px auto -webkit-focus-ring-color; +} diff --git a/components/page-footer/Survey.tsx b/components/page-footer/Survey.tsx index 7d62241f31..15f9b2dc51 100644 --- a/components/page-footer/Survey.tsx +++ b/components/page-footer/Survey.tsx @@ -6,6 +6,8 @@ import { useTranslation } from 'components/hooks/useTranslation' import { Link } from 'components/Link' import { sendEvent, EventType } from 'components/lib/events' +import styles from './Survey.module.scss' + enum ViewState { START = 'START', YES = 'YES', @@ -73,12 +75,12 @@ export const Survey = () => { {state !== ViewState.END && (
@@ -92,12 +94,12 @@ export const Survey = () => { diff --git a/components/page-header/Header.tsx b/components/page-header/Header.tsx index 0253c773aa..7c914022a1 100644 --- a/components/page-header/Header.tsx +++ b/components/page-header/Header.tsx @@ -86,7 +86,7 @@ export const Header = () => { {/* mobile header */}
-