diff --git a/.github/workflows/beta-test-2gp.yml b/.github/workflows/beta-test-2gp.yml index 3ace2bd..e9052b9 100644 --- a/.github/workflows/beta-test-2gp.yml +++ b/.github/workflows/beta-test-2gp.yml @@ -65,7 +65,7 @@ jobs: GITHUB_APP_KEY: "${{ secrets.github-app-key }}" steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Auth to DevHub run: /usr/local/bin/devhub.sh - name: Set default org diff --git a/.github/workflows/beta-test-env.yml b/.github/workflows/beta-test-env.yml index afb87ca..a1a2445 100644 --- a/.github/workflows/beta-test-env.yml +++ b/.github/workflows/beta-test-env.yml @@ -7,6 +7,11 @@ on: required: true default: 1GP Packaging Beta type: string + + run-test: + description: If true, run the ci_beta flow to test the beta as part of the job. Set to false to split ci_beta into a separate workflow + default: true + type: boolean debug: required: false default: false @@ -20,6 +25,11 @@ on: required: true github-token: required: true + github-app-id: + required: false + github-app-key: + required: false + jobs: beta-test: @@ -36,9 +46,13 @@ jobs: DEV_HUB_AUTH_URL: "${{ secrets.dev-hub-auth-url }}" PACKAGING_ORG_AUTH_URL: "${{ secrets.packaging-org-auth-url }}" CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' + + GITHUB_APP_ID: "${{ secrets.github-app-id }}" + GITHUB_APP_KEY: "${{ secrets.github-app-key }}" + steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Auth to DevHub run: /usr/local/bin/devhub.sh - name: Deploy to Packaging Org @@ -47,9 +61,10 @@ jobs: run: cci flow run release_beta --org packaging $([[ "${{ inputs.debug }}" == "true" ]] && echo " --debug") shell: bash - name: Run Beta Test + if: ${{ inputs.run-test }} run: cci flow run ci_beta --org beta - name: Delete Scratch Org - if: ${{ always() }} + if: ${{ always() }} && ${{ inputs.run-test }} run: | cci org scratch_delete beta shell: bash diff --git a/.github/workflows/beta-test-scratch.yml b/.github/workflows/beta-test-scratch.yml new file mode 100644 index 0000000..d267405 --- /dev/null +++ b/.github/workflows/beta-test-scratch.yml @@ -0,0 +1,50 @@ +name: Beta Test + +on: + workflow_call: + inputs: + debug: + required: false + default: false + type: boolean + secrets: + dev-hub-auth-url: + required: true + gh-email: + required: true + github-token: + required: true + github-app-id: + required: false + github-app-key: + required: false + +jobs: + beta-test: + name: "Beta Test in Scratch Org" + runs-on: ubuntu-latest + environment: ${{ inputs.env-name }} + container: + image: ghcr.io/muselab-d2x/d2x:cumulusci-next + options: --user root + credentials: + username: ${{ github.actor }} + password: ${{ secrets.github-token }} + env: + DEV_HUB_AUTH_URL: "${{ secrets.dev-hub-auth-url }}" + PACKAGING_ORG_AUTH_URL: "${{ secrets.packaging-org-auth-url }}" + CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' + GITHUB_APP_ID: "${{ secrets.github-app-id }}" + GITHUB_APP_KEY: "${{ secrets.github-app-key }}" + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Auth to DevHub + run: /usr/local/bin/devhub.sh + - name: Run Beta Test + run: cci flow run ci_beta --org beta + - name: Delete Scratch Org + if: ${{ always() }} + run: | + cci org scratch_delete beta + shell: bash diff --git a/.github/workflows/beta-test-unlocked.yml b/.github/workflows/beta-test-unlocked.yml index e6433da..a5259ce 100644 --- a/.github/workflows/beta-test-unlocked.yml +++ b/.github/workflows/beta-test-unlocked.yml @@ -25,7 +25,7 @@ jobs: CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Auth to DevHub run: /usr/local/bin/devhub.sh - name: Set default org diff --git a/.github/workflows/beta-test.yml b/.github/workflows/beta-test.yml index 6a004b2..d6836a8 100644 --- a/.github/workflows/beta-test.yml +++ b/.github/workflows/beta-test.yml @@ -12,6 +12,12 @@ on: github-token: required: true + github-app-id: + required: false + github-app-key: + required: false + + jobs: beta-test: name: "Beta Test" @@ -26,9 +32,13 @@ jobs: DEV_HUB_AUTH_URL: "${{ secrets.dev-hub-auth-url }}" PACKAGING_ORG_AUTH_URL: "${{ secrets.packaging-org-auth-url }}" CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' + + GITHUB_APP_ID: "${{ secrets.github-app-id }}" + GITHUB_APP_KEY: "${{ secrets.github-app-key }}" + steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Auth to DevHub run: /usr/local/bin/devhub.sh - name: Deploy to Packaging Org diff --git a/.github/workflows/check-no-org.yml b/.github/workflows/check-no-org.yml new file mode 100644 index 0000000..f6ec07c --- /dev/null +++ b/.github/workflows/check-no-org.yml @@ -0,0 +1,38 @@ +name: Check No Org + +on: + workflow_call: + inputs: + debug: + description: "Enable debug logging output for CumulusCI" + required: false + default: false + type: boolean + secrets: + github-token: + required: true + +jobs: + check-no-org: + name: "Check No Org" + runs-on: ubuntu-latest + container: + image: ghcr.io/muselab-d2x/d2x:cumulusci-next-snapshots + options: --user root + credentials: + username: "${{ github.actor }}" + password: "${{ secrets.github-token }}" + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Run Checks + run: | + set -e { + cci task run check_no_org \ + $([[ "${{ inputs.debug }}" == "true" ]] && echo " --debug") + } || { + echo "::error::Failed to run checks. Running cci error info..." + cci error info + exit 1 + } + shell: bash diff --git a/.github/workflows/configure-org-for-testing.yml b/.github/workflows/configure-org-for-testing.yml new file mode 100644 index 0000000..46f3916 --- /dev/null +++ b/.github/workflows/configure-org-for-testing.yml @@ -0,0 +1,73 @@ +name: Configure Org for Testing + +on: + workflow_call: + inputs: + org: + required: false + default: feature + type: string + debug: + required: false + default: false + type: boolean + secrets: + dev-hub-auth-url: + required: false + dev-hub-username: + required: false + dev-hub-client-id: + required: false + dev-hub-private-key: + required: false + gh-email: + required: true + github-token: + required: true + github-app-id: + required: false + github-app-key: + required: false + +jobs: + configure-org-for-testing: + name: "Configure Org for Testing" + runs-on: ubuntu-latest + container: + image: ghcr.io/muselab-d2x/d2x:cumulusci-next-snapshots + options: --user root + credentials: + username: "${{ github.actor }}" + password: "${{ secrets.github-token }}" + steps: + - name: D2X Image Details + run: | + echo "D2X Docker Image: ghcr.io/muselab-d2x/d2x" + echo "D2X Docker Tag: cumulusci-next-snapshots" + echo "D2X Docker Image: ghcr.io/muselab-d2x/d2x:cumulusci-next-snapshots" >> $GITHUB_STEP_SUMMARY + shell: bash + + - name: Checkout + uses: actions/checkout@v4 + + - name: Auth to DevHub + run: /usr/local/bin/devhub.sh + env: + DEV_HUB_AUTH_URL: "${{ secrets.dev-hub-auth-url }}" + DEV_HUB_USERNAME: "${{ secrets.dev-hub-username }}" + DEV_HUB_CLIENT_ID: "${{ secrets.dev-hub-client-id }}" + DEV_HUB_PRIVATE_KEY: "${{ secrets.dev-hub-private-key }}" + + - name: Set ${{ inputs.org }} org as default org + run: cci org default ${{ inputs.org }} + + - name: Configure Org for Testing + id: configure_org + env: + GITHUB_TOKEN: "${{ secrets.github-token }}" + CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' + GITHUB_APP_ID: "${{ secrets.github-app-id }}" + GITHUB_APP_KEY: "${{ secrets.github-app-key }}" + run: | + cci flow run ci_feature_2gp --skip-from run-tests + shell: bash diff --git a/.github/workflows/create-feature-test-package.yml b/.github/workflows/create-feature-test-package.yml new file mode 100644 index 0000000..4932a12 --- /dev/null +++ b/.github/workflows/create-feature-test-package.yml @@ -0,0 +1,88 @@ +name: Create Feature Test Package + +on: + workflow_call: + inputs: + org: + required: false + default: feature + type: string + debug: + required: false + default: false + type: boolean + docker_image: + required: false + default: ghcr.io/muselab-d2x/d2x + type: string + docker_tag: + type: string + required: false + default: cumulusci-next-snapshots + secrets: + dev-hub-auth-url: + required: false + dev-hub-username: + required: false + dev-hub-client-id: + required: false + dev-hub-private-key: + required: false + gh-email: + required: true + github-token: + required: true + github-app-id: + required: false + github-app-key: + required: false + +jobs: + create-feature-test-package: + name: "Create Feature Test Package" + runs-on: ubuntu-latest + container: + image: ${{ inputs.docker_image }}:${{ inputs.docker_tag }} + options: --user root + credentials: + username: "${{ github.actor }}" + password: "${{ secrets.github-token }}" + steps: + - name: D2X Image Details + run: | + echo "D2X Docker Image: ${{ inputs.docker_image }}" + echo "D2X Docker Tag: ${{ inputs.docker_tag }}" + echo "D2X Docker Image: `${{ inputs.docker_image }}:${{ inputs.docker_tag }}`" >> $GITHUB_STEP_SUMMARY + shell: bash + - name: Checkout + uses: actions/checkout@v4 + - name: Auth to DevHub + run: /usr/local/bin/devhub.sh + env: + DEV_HUB_AUTH_URL: "${{ secrets.dev-hub-auth-url }}" + DEV_HUB_USERNAME: "${{ secrets.dev-hub-username }}" + DEV_HUB_CLIENT_ID: "${{ secrets.dev-hub-client-id }}" + DEV_HUB_PRIVATE_KEY: "${{ secrets.dev-hub-private-key }}" + - name: Set ${{ inputs.org }} org as default org + run: cci org default ${{ inputs.org }} + - name: Build Feature Test Package + env: + GITHUB_TOKEN: "${{ secrets.github-token }}" + CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' + GITHUB_APP_ID: "${{ secrets.github-app-id }}" + GITHUB_APP_KEY: "${{ secrets.github-app-key }}" + run: cci flow run build_feature_test_package $([[ "${{ inputs.debug }}" == "true" ]] && echo " --debug") | tee cumulusci-flow.log + shell: bash + - name: Set Commit Status + env: + GITHUB_TOKEN: "${{ secrets.github-token }}" + run: | + VERSION=$(cat cumulusci-flow.log | grep -o -E -m 1 "04t[a-zA-Z0-9]{15}") + gh api \ + --method POST \ + -H "Accept: application/vnd.github.v3+json" \ + '/repos/${{ github.repository }}/statuses/${{ github.sha }}' \ + -f state='success' \ + -f description="version_id: $VERSION" \ + -f context='Build Feature Test Package' + shell: bash diff --git a/.github/workflows/create-org.yml b/.github/workflows/create-org.yml new file mode 100644 index 0000000..1f729ab --- /dev/null +++ b/.github/workflows/create-org.yml @@ -0,0 +1,76 @@ +name: Create Org + +on: + workflow_call: + inputs: + scratchdef_path: + description: "Path to the scratch definition file" + required: false + type: string + cli_options: + description: "CLI options for creating the scratch org" + required: false + type: string + scratch_profile_name: + description: "CumulusCI scratch profile name" + required: false + default: feature + type: string + scratchdef_json: + description: "Scratch definition as JSON" + required: false + type: string + secrets: + dev-hub-auth-url: + required: true + dev-hub-username: + required: true + dev-hub-client-id: + required: true + dev-hub-private-key: + required: true + gh-email: + required: true + github-token: + required: true + +jobs: + create-org: + name: "Create Org" + runs-on: ubuntu-latest + container: + image: ghcr.io/muselab-d2x/d2x:cumulusci-next-snapshots + options: --user root + credentials: + username: "${{ github.actor }}" + password: "${{ secrets.github-token }}" + env: + DEV_HUB_AUTH_URL: "${{ secrets.dev-hub-auth-url }}" + DEV_HUB_USERNAME: "${{ secrets.dev-hub-username }}" + DEV_HUB_CLIENT_ID: "${{ secrets.dev-hub-client-id }}" + DEV_HUB_PRIVATE_KEY: "${{ secrets.dev-hub-private-key }}" + CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Auth to DevHub + run: /usr/local/bin/devhub.sh + + - name: Create Scratch Org + run: | + if [ -n "${{ inputs.scratchdef_path }}" ]; then + cci org scratch ${{ inputs.scratch_profile_name }} -f ${{ inputs.scratchdef_path }} ${{ inputs.cli_options }} + elif [ -n "${{ inputs.scratchdef_json }}" ]; then + echo "${{ inputs.scratchdef_json }}" > scratchdef.json + cci org scratch ${{ inputs.scratch_profile_name }} -f scratchdef.json ${{ inputs.cli_options }} + else + cci org scratch ${{ inputs.scratch_profile_name }} ${{ inputs.cli_options }} + fi + + - name: Create Access Token Session Environment + run: | + ACCESS_TOKEN=$(cci org info ${{ inputs.scratch_profile_name }} --json | jq -r '.access_token') + INSTANCE_URL=$(cci org info ${{ inputs.scratch_profile_name }} --json | jq -r '.instance_url') + echo "ACCESS_TOKEN=${ACCESS_TOKEN}" >> $GITHUB_ENV + echo "INSTANCE_URL=${INSTANCE_URL}" >> $GITHUB_ENV diff --git a/.github/workflows/create-test-scratch-org.yml b/.github/workflows/create-test-scratch-org.yml new file mode 100644 index 0000000..3f2cb1f --- /dev/null +++ b/.github/workflows/create-test-scratch-org.yml @@ -0,0 +1,76 @@ +name: Create Test Scratch Org + +on: + workflow_call: + inputs: + scratchdef_path: + description: "Path to the scratch definition file" + required: false + type: string + cli_options: + description: "CLI options for creating the scratch org" + required: false + type: string + scratch_profile_name: + description: "CumulusCI scratch profile name" + required: false + default: feature + type: string + scratchdef_json: + description: "Scratch definition as JSON" + required: false + type: string + secrets: + dev-hub-auth-url: + required: true + dev-hub-username: + required: true + dev-hub-client-id: + required: true + dev-hub-private-key: + required: true + gh-email: + required: true + github-token: + required: true + +jobs: + create-test-scratch-org: + name: "Create Test Scratch Org" + runs-on: ubuntu-latest + container: + image: ghcr.io/muselab-d2x/d2x:cumulusci-next-snapshots + options: --user root + credentials: + username: "${{ github.actor }}" + password: "${{ secrets.github-token }}" + env: + DEV_HUB_AUTH_URL: "${{ secrets.dev-hub-auth-url }}" + DEV_HUB_USERNAME: "${{ secrets.dev-hub-username }}" + DEV_HUB_CLIENT_ID: "${{ secrets.dev-hub-client-id }}" + DEV_HUB_PRIVATE_KEY: "${{ secrets.dev-hub-private-key }}" + CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Auth to DevHub + run: /usr/local/bin/devhub.sh + + - name: Create Scratch Org + run: | + if [ -n "${{ inputs.scratchdef_path }}" ]; then + cci org scratch ${{ inputs.scratch_profile_name }} -f ${{ inputs.scratchdef_path }} ${{ inputs.cli_options }} + elif [ -n "${{ inputs.scratchdef_json }}" ]; then + echo "${{ inputs.scratchdef_json }}" > scratchdef.json + cci org scratch ${{ inputs.scratch_profile_name }} -f scratchdef.json ${{ inputs.cli_options }} + else + cci org scratch ${{ inputs.scratch_profile_name }} ${{ inputs.cli_options }} + fi + + - name: Create Access Token Session Environment + run: | + ACCESS_TOKEN=$(cci org info ${{ inputs.scratch_profile_name }} --json | jq -r '.access_token') + INSTANCE_URL=$(cci org info ${{ inputs.scratch_profile_name }} --json | jq -r '.instance_url') + echo "ACCESS_TOKEN=${ACCESS_TOKEN}" >> $GITHUB_ENV + echo "INSTANCE_URL=${INSTANCE_URL}" >> $GITHUB_ENV diff --git a/.github/workflows/dispose-org.yml b/.github/workflows/dispose-org.yml new file mode 100644 index 0000000..73e1af4 --- /dev/null +++ b/.github/workflows/dispose-org.yml @@ -0,0 +1,75 @@ +name: Dispose Org + +on: + workflow_call: + inputs: + org_name: + description: "The name of the scratch org to dispose of" + required: true + type: string + keep_org: + description: "If true, the org will not be deleted" + required: false + default: false + type: boolean + create_snapshot: + description: "If true, a snapshot will be created before disposing of the org" + required: false + default: false + type: boolean + snapshot_name: + description: "The name of the snapshot to create" + required: false + type: string + secrets: + dev-hub-auth-url: + required: false + dev-hub-username: + required: false + dev-hub-client-id: + required: false + dev-hub-private-key: + required: false + gh-email: + required: true + github-token: + required: true + github-app-id: + required: false + github-app-key: + required: false + +jobs: + dispose-org: + name: "Dispose Org" + runs-on: ubuntu-latest + container: + image: ghcr.io/muselab-d2x/d2x:cumulusci-next-snapshots + options: --user root + credentials: + username: "${{ github.actor }}" + password: "${{ secrets.github-token }}" + env: + DEV_HUB_AUTH_URL: "${{ secrets.dev-hub-auth-url }}" + DEV_HUB_USERNAME: "${{ secrets.dev-hub-username }}" + DEV_HUB_CLIENT_ID: "${{ secrets.dev-hub-client-id }}" + DEV_HUB_PRIVATE_KEY: "${{ secrets.dev-hub-private-key }}" + CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' + GITHUB_APP_ID: "${{ secrets.github-app-id }}" + GITHUB_APP_KEY: "${{ secrets.github-app-key }}" + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Auth to DevHub + run: /usr/local/bin/devhub.sh + + - name: Create Snapshot + if: ${{ inputs.create_snapshot }} + run: | + cci task run create_snapshot --snapshot-name ${{ inputs.snapshot_name }} + + - name: Delete Scratch Org + if: ${{ !inputs.keep_org }} + run: cci org scratch_delete ${{ inputs.org_name }} + shell: bash diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..684d89d --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,95 @@ +name: Build Multi-Arch Docker Images + +on: + push: + branches: + - main + - cumulusci-next** + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + target: [no-browser, browser] + platform: [linux/amd64, linux/arm64] + steps: + - name: Checkout repository + + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set environment variables + run: | + if [ "${{ github.ref_name }}" == "main" ]; then + echo "IMAGE_TAG=latest" >> $GITHUB_ENV + else + + echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV + fi + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: ${{ github.event_name == 'push' }} + tags: | + ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}${{ matrix.target == 'browser' && '-browser' || '' }}${{ matrix.platform == 'linux/arm64' && '-arm64' || '' }} + platforms: ${{ matrix.platform }} + target: ${{ matrix.target }} + cache-from: type=gha + cache-to: type=gha,mode=max + + merge-manifests: + needs: build + runs-on: ubuntu-latest + steps: + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set environment variables + run: | + if [ "${{ github.ref_name }}" == "main" ]; then + echo "IMAGE_TAG=latest" >> $GITHUB_ENV + else + + echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV + + fi + + - name: Create and push multi-arch manifests + run: | + # For no-browser + docker buildx imagetools create -t ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }} \ + ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }} \ + ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}-arm64 + + # For browser + docker buildx imagetools create -t ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}-browser \ + ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}-browser \ + ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}-browser-arm64 + + - name: Inspect manifests + run: | + echo "Inspecting no-browser manifest:" + docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }} + echo "Inspecting browser manifest:" + docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}-browser diff --git a/.github/workflows/docker/publish.yml b/.github/workflows/docker/publish.yml new file mode 100644 index 0000000..7588111 --- /dev/null +++ b/.github/workflows/docker/publish.yml @@ -0,0 +1,91 @@ +name: Build Multi-Arch Docker Images + +on: + push: + branches: + - main + - cumulusci-next** + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + target: [no-browser, browser] + platform: [linux/amd64, linux/arm64] + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set environment variables + run: | + if [ "${{ github.ref_name }}" == "main" ]; then + echo "IMAGE_TAG=latest" >> $GITHUB_ENV + else + IMAGE_TAG=$(echo "${{ github.ref_name }}" | sed -e 's/\//-/g') + echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV + fi + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + push: ${{ github.event_name == 'push' }} + tags: | + ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}${{ matrix.target == 'browser' && '-browser' || '' }}${{ matrix.platform == 'linux/arm64' && '-arm64' || '' }} + platforms: ${{ matrix.platform }} + target: ${{ matrix.target }} + cache-from: type=gha + cache-to: type=gha,mode=max + + merge-manifests: + needs: build + runs-on: ubuntu-latest + steps: + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set environment variables + run: | + if [ "${{ github.ref_name }}" == "main" ]; then + echo "IMAGE_TAG=latest" >> $GITHUB_ENV + else + echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV + fi + + - name: Create and push multi-arch manifests + run: | + # For no-browser + docker buildx imagetools create -t ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }} \ + ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }} \ + ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}-arm64 + + # For browser + docker buildx imagetools create -t ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}-browser \ + ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}-browser \ + ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}-browser-arm64 + + - name: Inspect manifests + run: | + echo "Inspecting no-browser manifest:" + docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }} + echo "Inspecting browser manifest:" + docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}-browser diff --git a/.github/workflows/feature-test-2gp.yml b/.github/workflows/feature-test-2gp.yml index be510bc..7f43fea 100644 --- a/.github/workflows/feature-test-2gp.yml +++ b/.github/workflows/feature-test-2gp.yml @@ -85,7 +85,7 @@ jobs: GITHUB_APP_ID: "${{ secrets.github-app-id }}" GITHUB_APP_KEY: "${{ secrets.github-app-key }}" run: | - cci flow run ci_feature_2gp --use-snapshots + cci flow run ci_feature_2gp --use-snapshots shell: bash - name: Save Org to GitHub Environment @@ -96,10 +96,9 @@ jobs: GITHUB_APP_KEY: ${{ secrets.github-app-key }} GITHUB_TOKEN: ${{ secrets.github-token }} with: - org-alias: ${{ inputs.org }} - create-environment: 'true' - environment-name: ${{ inputs.environment_name }} - + org-alias: ${{ inputs.org }} + create-environment: "true" + environment-name: ${{ inputs.environment_name }} - name: Capture CumulusCI Build History if: always() @@ -136,7 +135,7 @@ jobs: echo "Feature Test step failed. Failing the job." exit 1 fi - + # Check for any failed steps FAILED_STEPS=$(cat $GITHUB_OUTPUT | grep -c "failure") echo "Failed steps: $FAILED_STEPS" @@ -144,6 +143,6 @@ jobs: echo "One or more steps failed. Failing the job." exit 1 fi - + echo "All steps completed successfully." - shell: bash \ No newline at end of file + shell: bash diff --git a/.github/workflows/feature-test-unlocked.yml b/.github/workflows/feature-test-unlocked.yml index 90d145d..22847d6 100644 --- a/.github/workflows/feature-test-unlocked.yml +++ b/.github/workflows/feature-test-unlocked.yml @@ -41,7 +41,7 @@ jobs: CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Auth to DevHub run: /usr/local/bin/devhub.sh - name: Set feature org as default org diff --git a/.github/workflows/investigate-1gp.yml b/.github/workflows/investigate-1gp.yml index 6ed217f..9063d77 100644 --- a/.github/workflows/investigate-1gp.yml +++ b/.github/workflows/investigate-1gp.yml @@ -40,11 +40,11 @@ jobs: cci task run dx_convert_from fi shell: bash - - name: Prepare Managed Source - run: cci task run create_managed_src + #- name: Prepare Managed Source + # run: cci task run create_managed_src - name: Update Package XML for Packaged Deploy run: cci task run update_package_xml - - name: Validate-Only Deploy with Tests to Packaging Org - run: cci task run deploy --org packaging --path src --check-only True + #- name: Validate-Only Deploy with Tests to Packaging Org + # run: cci task run deploy --org packaging --path src --check-only True - name: Dry Run of uninstall_packaged_incremental run: cci task run uninstall_packaged_incremental --org packaging --dry-run True diff --git a/.github/workflows/org-login-slack.yml b/.github/workflows/org-login-slack.yml index c7aab18..a14958e 100644 --- a/.github/workflows/org-login-slack.yml +++ b/.github/workflows/org-login-slack.yml @@ -1,49 +1,140 @@ -name: Org Login URL to Slack DM +# File: .github/workflows/request-login-url.yml + +name: Request Org Login URL on: - workflow_call: - inputs: - environment: - description: The name of the environment - required: true - type: string - slack_username: - description: Slack username to send the login URL - required: true - type: string - secrets: - slack-bot-token: - required: true - github-token: - required: true + workflow_call: + inputs: + org: + description: "The name of the org to get the login URL for. NOTE: Do not select orgs starting with 'Snapshot:'" + required: true + type: string + slack_username: + description: "The Slack username to send the DM to" + required: true + type: string + environment: + description: "Select the environment to use (e.g., DevHub)" + required: true + type: environment + secrets: + SFDX_AUTH_URL: + description: "Salesforce DX Auth URL" + required: true + SLACK_BOT_TOKEN: + description: "Slack Bot Token" + required: true jobs: - d2x-login-url: - name: Use d2x to generate a login url - runs-on: ubuntu-latest - environment: ${{ github.event.inputs.environment }} - steps: - - run: pip install git+https://github.com/muselab-d2x/d2x.git@jlantz/update-auth-structure - - - id: generate_login_url - name: Generate Login URL for ${{ github.event.inputs.environment }} - env: - SFDX_AUTH_URL: ${{ secrets.sfdx-auth-url }} - run: | - set -eo pipefail - d2x sf auth login | tail -1 > login_url.txt - - - name: Send Slack DM - if: success() - env: - SLACK_BOT_TOKEN: ${{ secrets.slack-bot-token }} - run: | - echo "login_url=$(cat login_url.txt)" >> $GITHUB_OUTPUT - rm login_url.txt - curl -X POST -H "Authorization: Bearer $SLACK_BOT_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "channel": "@${{ github.event.inputs.slack_username }}", - "text": "Here'"'"'s your Salesforce login URL for ${{ github.event.inputs.environment }}: ${{ steps.generate_login_url.outputs.login_url }}" - }' \ - https://slack.com/api/chat.postMessage + send-login-url: + runs-on: ubuntu-latest + environment: ${{ inputs.environment }} + steps: + - name: Check SFDX_AUTH_URL + run: | + if [ -z "${{ secrets.SFDX_AUTH_URL }}" ]; then + echo "Error: SFDX_AUTH_URL is not set." + exit 1 + fi + + - name: Cache d2x + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install d2x + run: | + pip install git+https://github.com/muselab-d2x/d2x.git@jlantz/update-auth-structure + d2x --version + + - id: generate_login_url + name: Generate Login URL + env: + SFDX_AUTH_URL: ${{ secrets.SFDX_AUTH_URL }} + run: | + set -eo pipefail + # Generate the login URL and store it in a variable + login_url=$(d2x sf auth login | tail -1) + # Store the login URL in a temporary file (do not print it) + echo "$login_url" > login_url.txt + + - name: Send Slack DM + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + ORG: ${{ inputs.org }} + SLACK_USERNAME: ${{ inputs.slack_username }} + run: | + set -e + + # Validate inputs + if [ -z "$ORG" ] || [ -z "$SLACK_USERNAME" ]; then + echo "Error: ORG and SLACK_USERNAME must be provided." + exit 1 + fi + + # Read the login URL from the file (do not print it) + login_url=$(cat login_url.txt) + + # Clean up the login URL file immediately + rm login_url.txt + + # Retrieve the user ID based on the Slack username + USER_INFO=$(curl -s -X POST -H "Authorization: Bearer $SLACK_BOT_TOKEN" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + --data-urlencode "username=$SLACK_USERNAME" \ + https://slack.com/api/users.lookupByUsername) + + USER_ID=$(echo "$USER_INFO" | jq -r '.user.id') + + if [ "$USER_ID" == "null" ] || [ -z "$USER_ID" ]; then + error_message=$(echo "$USER_INFO" | jq -r '.error') + echo "Error: Failed to retrieve Slack user ID - $error_message" + exit 1 + fi + + # Construct the Slack message (do not print the login URL) + TEXT="Here is your Salesforce login URL for ${ORG}." + + # Send the login URL as a private message + JSON_DATA=$(jq -n \ + --arg channel "$USER_ID" \ + --arg text "$TEXT" \ + --arg login_url "$login_url" \ + '{ + channel: $channel, + text: $text, + blocks: [ + { + type: "section", + text: { + type: "mrkdwn", + text: $text + } + }, + { + type: "section", + text: { + type: "mrkdwn", + text: "<\($login_url)|Click here to log in>" + } + } + ] + }') + + # Send the message via Slack API + response=$(curl -s -X POST -H "Authorization: Bearer $SLACK_BOT_TOKEN" \ + -H "Content-Type: application/json" \ + -d "$JSON_DATA" \ + https://slack.com/api/chat.postMessage) + + # Enhanced error handling + if [[ $(echo "$response" | jq -r '.ok') != "true" ]]; then + error_message=$(echo "$response" | jq -r '.error') + echo "Error: Failed to send Slack DM - $error_message" + exit 1 + fi + + echo "Slack message sent successfully." \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6ab5bc0..5f00d72 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,9 +1,6 @@ name: Publish Python 🐍 distribution πŸ“¦ to PyPI and TestPyPI on: - push: - tags: - - "*" workflow_dispatch: jobs: @@ -18,8 +15,11 @@ jobs: with: python-version: "3.x" - name: Install pypa/build - run: | - python3 -m pip install build --user + run: >- + python3 -m + pip install + build + --user - name: Build a binary wheel and a source tarball run: python3 -m build - name: Store the distribution packages @@ -29,7 +29,8 @@ jobs: path: dist/ publish-to-pypi: - name: Publish Python 🐍 distribution πŸ“¦ to PyPI + name: >- + Publish Python 🐍 distribution πŸ“¦ to PyPI if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes needs: - build @@ -50,7 +51,9 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 github-release: - name: Sign the Python 🐍 distribution πŸ“¦ with Sigstore and upload them to GitHub Release + name: >- + Sign the Python 🐍 distribution πŸ“¦ with Sigstore + and upload them to GitHub Release needs: - publish-to-pypi runs-on: ubuntu-latest @@ -66,21 +69,29 @@ jobs: name: python-package-distributions path: dist/ - name: Sign the dists with Sigstore - uses: sigstore/gh-action-sigstore-python@v2.1.1 + uses: sigstore/gh-action-sigstore-python@v3.0.0 with: - inputs: | + inputs: >- ./dist/*.tar.gz ./dist/*.whl - name: Create GitHub Release env: GITHUB_TOKEN: ${{ github.token }} - run: | - gh release create '${{ github.ref_name }}' --repo '${{ github.repository }}' --notes "" + run: >- + gh release create + '${{ github.ref_name }}' + --repo '${{ github.repository }}' + --notes "" - name: Upload artifact signatures to GitHub Release env: GITHUB_TOKEN: ${{ github.token }} - run: | - gh release upload '${{ github.ref_name }}' dist/** --repo '${{ github.repository }}' + # Upload to GitHub Release using the `gh` CLI. + # `dist/` contains the built packages, and the + # sigstore-produced signatures and certificates. + run: >- + gh release upload + '${{ github.ref_name }}' dist/** + --repo '${{ github.repository }}' publish-to-testpypi: name: Publish Python 🐍 distribution πŸ“¦ to TestPyPI diff --git a/.github/workflows/release-1gp-env.yml b/.github/workflows/release-1gp-env.yml index af25a5b..f321e89 100644 --- a/.github/workflows/release-1gp-env.yml +++ b/.github/workflows/release-1gp-env.yml @@ -37,7 +37,7 @@ jobs: CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Auth to DevHub run: /usr/local/bin/devhub.sh - name: Deploy to Packaging Org diff --git a/.github/workflows/release-1gp.yml b/.github/workflows/release-1gp.yml index 9cbb379..f935ee1 100644 --- a/.github/workflows/release-1gp.yml +++ b/.github/workflows/release-1gp.yml @@ -7,6 +7,16 @@ on: required: false description: "The name of the release to upload to the production org." type: string + skip-deploy: + required: false + description: If true, don't deploy to the packaging org. Just release what's in the org currently + type: boolean + default: false + skip-test: + required: false + description: If true, don't test the package. Just upload and pass the build if the upload and GitHub Release are created successfully + type: boolean + default: false secrets: dev-hub-auth-url: required: true @@ -33,18 +43,25 @@ jobs: CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Auth to DevHub run: /usr/local/bin/devhub.sh + - name: Report Inputs + run: | + echo "Release Name: ${{ inputs.release-name }}" | tee -a "${GITHUB_STEP_SUMMARY}" + echo 'Command: cci flow run release_production --org packaging $([[ "${{ inputs.release-name }}" ]] && echo " -o upload_production__version_name_template \${{ inputs.release-name }}")' | tee -a "${GITHUB_STEP_SUMMARY}" - name: Deploy to Packaging Org + if: ${{ inputs.skip-deploy == false }} run: cci flow run ci_master --org packaging - name: Build Production Package - run: cci flow run release_production --org packaging $([[ "${{ inputs.release-name }}" ]] && echo " -o upload_production__name ${{ inputs.release-name }}") + run: | + cci flow run release_production --org packaging $([[ "${{ inputs.release-name }}" ]] && echo " -o upload_production__version_name_template ${{ inputs.release-name }}") shell: bash - - name: Run Beta Test + - name: Run Release Test in Scratch Org + if: ${{ inputs.skip-test == false }} run: cci flow run ci_release --org release - name: Delete Scratch Org - if: ${{ always() }} + if: ${{ always() }} && ${{ inputs.skip-test == false }} run: | cci org scratch_delete release shell: bash diff --git a/.github/workflows/release-2gp-env.yml b/.github/workflows/release-2gp-env.yml index 17009b7..50a823d 100644 --- a/.github/workflows/release-2gp-env.yml +++ b/.github/workflows/release-2gp-env.yml @@ -35,7 +35,7 @@ jobs: CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Auth to DevHub run: /usr/local/bin/devhub.sh - name: Set default org diff --git a/.github/workflows/release-2gp-unlocked.yml b/.github/workflows/release-2gp-unlocked.yml index a44f5d4..9f68fdc 100644 --- a/.github/workflows/release-2gp-unlocked.yml +++ b/.github/workflows/release-2gp-unlocked.yml @@ -25,7 +25,7 @@ jobs: CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Auth to DevHub run: /usr/local/bin/devhub.sh - name: Set default org diff --git a/.github/workflows/release-2gp.yml b/.github/workflows/release-2gp.yml index 47ff4ac..24bc0ea 100644 --- a/.github/workflows/release-2gp.yml +++ b/.github/workflows/release-2gp.yml @@ -69,7 +69,7 @@ jobs: steps: - name: Checkout id: checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Auth to Orgs id: auth_orgs run: /usr/local/bin/devhub.sh diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000..ca14e49 --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,120 @@ +name: Run Tests + +on: + workflow_call: + inputs: + org: + required: false + default: feature + type: string + debug: + required: false + default: false + type: boolean + secrets: + dev-hub-auth-url: + required: false + dev-hub-username: + required: false + dev-hub-client-id: + required: false + dev-hub-private-key: + required: false + gh-email: + required: true + github-token: + required: true + github-app-id: + required: false + github-app-key: + required: false + +jobs: + run-tests: + name: "Run Tests" + runs-on: ubuntu-latest + container: + image: ghcr.io/muselab-d2x/d2x:cumulusci-next-snapshots + options: --user root + credentials: + username: "${{ github.actor }}" + password: "${{ secrets.github-token }}" + steps: + - name: D2X Image Details + run: | + echo "D2X Docker Image: ghcr.io/muselab-d2x/d2x" + echo "D2X Docker Tag: cumulusci-next-snapshots" + echo "D2X Docker Image: ghcr.io/muselab-d2x/d2x:cumulusci-next-snapshots" >> $GITHUB_STEP_SUMMARY + shell: bash + + - name: Checkout + uses: actions/checkout@v4 + + - name: Auth to DevHub + run: /usr/local/bin/devhub.sh + env: + DEV_HUB_AUTH_URL: "${{ secrets.dev-hub-auth-url }}" + DEV_HUB_USERNAME: "${{ secrets.dev-hub-username }}" + DEV_HUB_CLIENT_ID: "${{ secrets.dev-hub-client-id }}" + DEV_HUB_PRIVATE_KEY: "${{ secrets.dev-hub-private-key }}" + + - name: Set ${{ inputs.org }} org as default org + run: cci org default ${{ inputs.org }} + + - name: Run Tests + id: run_tests + env: + GITHUB_TOKEN: "${{ secrets.github-token }}" + CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }' + GITHUB_APP_ID: "${{ secrets.github-app-id }}" + GITHUB_APP_KEY: "${{ secrets.github-app-key }}" + run: | + cci flow run ci_feature_2gp --start-from run-tests + shell: bash + + - name: Capture CumulusCI Build History + if: always() + run: | + cci history list + cci history dependencies + cci history dependencies --json > cci_dependencies_history.json + cci history list --json > cci_build_history.json + shell: bash + + - name: Upload CumulusCI Dependencies History + if: always() + uses: actions/upload-artifact@v4 + with: + name: cci-dependencies-history + path: cci_dependencies_history.json + + - name: Upload CumulusCI Build History + if: always() + uses: actions/upload-artifact@v4 + with: + name: cci-build-history + path: cci_build_history.json + + - name: Delete Scratch Org + if: always() + run: cci org scratch_delete ${{ inputs.org }} + shell: bash + + - name: Check Job Status + if: always() + run: | + if [[ "${{ steps.run_tests.outcome }}" == "failure" ]]; then + echo "Run Tests step failed. Failing the job." + exit 1 + fi + + # Check for any failed steps + FAILED_STEPS=$(cat $GITHUB_OUTPUT | grep -c "failure") + echo "Failed steps: $FAILED_STEPS" + if [[ $FAILED_STEPS -gt 0 ]]; then + echo "One or more steps failed. Failing the job." + exit 1 + fi + + echo "All steps completed successfully." + shell: bash diff --git a/.gitignore b/.gitignore index 2466da5..16539c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ # Python __pycache__/ -*.pyc \ No newline at end of file +*.pyc +.DS_Store +.swp diff --git a/README.md b/README.md index eddcae3..b6d1856 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ - D2X lets teams deliver repeatable, composable Salesforce products and solutions that align with Salesforce's [Well-Architected Framework](https://architect.salesforce.com/well-architected/overview). D2X defines a container image for Salesforce development, build, and delivery using CumulusCI and Salesforce CLI. This gives teams a cconsistent runtime environment for automation used in across the entire software product lifecycle. MuseLab created D2X as the framework for all of our [services engagements](https://muselab.com/services), and we are proud to share it freely with the entire Salesforce ecosystem. -See [D2X documentation](https://d2x.readthedocs.io) for more details on using D2X β€” or try it yourself right now via [D2X Launchpad](https://launchpad.muselab.com)! +See [D2X documentation](https://d2x.readthedocs.io) for more details on using D2X β€” or try it yourself right now via [D2X Launchpad](https://launchpad.muselab.com)! Stay tuned for details on how to contribute! - diff --git a/docs/architecture/automation.md b/docs/architecture/automation.md new file mode 100644 index 0000000..933c636 --- /dev/null +++ b/docs/architecture/automation.md @@ -0,0 +1,44 @@ +# πŸ€– Automation Architecture + +## Automation Layers + +D2X's automation architecture is built on multiple layers to ensure efficient and reliable automation of your Salesforce workflows. + +### 1. Workflow Orchestration + +- **GitHub Actions**: Use GitHub Actions to orchestrate complex workflows. +- **Reusable Workflows**: Create reusable workflows to standardize automation across projects. +- **Event-Driven Automation**: Trigger workflows based on events such as code commits, pull requests, and issue updates. + +### 2. Task Automation + +- **CumulusCI**: Leverage CumulusCI to automate common Salesforce tasks such as deployments, data loading, and testing. +- **Custom Scripts**: Write custom scripts to automate specific tasks unique to your project. +- **Job Scheduling**: Schedule jobs to run at specific times or intervals. + +### 3. Integration Automation + +- **API Integrations**: Automate interactions with external systems using APIs. +- **Webhooks**: Use webhooks to trigger automation based on events in external systems. +- **Data Synchronization**: Automate data synchronization between Salesforce and other systems. + +## Workflow Components + +D2X workflows are built from smaller, reusable components that can be: + +- Combined in different ways +- Customized as needed +- Versioned independently +- Shared across repositories + +### Core Components + +- **Authentication**: Handle authentication and authorization for accessing Salesforce and other systems. +- **Session Management**: Manage sessions and tokens for secure access. +- **Secret Handling**: Securely manage secrets and credentials. +- **Deployment**: Automate the deployment of Salesforce metadata and configurations. +- **Testing**: Automate testing of Salesforce applications and integrations. +- **Validation**: Validate configurations and deployments to ensure they meet requirements. +- **Notification**: Send notifications and alerts based on workflow outcomes. + +[Back to Architecture Overview](./index.md) diff --git a/docs/architecture/credentials.md b/docs/architecture/credentials.md new file mode 100644 index 0000000..713ebb9 --- /dev/null +++ b/docs/architecture/credentials.md @@ -0,0 +1,23 @@ +# Credential Management + +## Credential Storage + +Credential storage is a critical aspect of D2X's security architecture. D2X leverages GitHub's Environments feature to securely store long-lived org credentials (SFDX auth URLs). These credentials are stored in the Base Environment, which implements protection rules and approvals to ensure secure access. + +### Key Features + +- **Secure Storage**: Long-lived org credentials are securely stored in GitHub Environments. +- **Protection Rules**: Access to credentials is governed by protection rules and approvals. +- **Audit Logs**: All access and operations are logged for auditing purposes. + +## Access Management + +Access management in D2X is designed to provide temporary, scoped access to credentials. The Session Environment contains temporary access tokens that auto-expire after a configured time. These tokens can be instantly revoked and are scoped to specific jobs and workflows. + +### Key Features + +- **Temporary Access Tokens**: Access tokens are temporary and auto-expire after a configured time. +- **Scoped Access**: Tokens are scoped to specific jobs and workflows. +- **Instant Revocation**: Tokens can be instantly revoked if needed. + +[Back to Architecture Overview](./index.md) diff --git a/docs/architecture/environments.md b/docs/architecture/environments.md new file mode 100644 index 0000000..c24e757 --- /dev/null +++ b/docs/architecture/environments.md @@ -0,0 +1,11 @@ +# Environment Configuration + +## Base Environment + +The Base Environment is responsible for storing long-lived org credentials (SFDX auth URLs) and implementing protection rules and approvals. It handles token exchange requests and maintains audit logs. + +## Session Environment + +The Session Environment contains temporary access tokens that auto-expire after a configured time. It can be instantly revoked and is scoped to specific jobs/workflows. + +[Back to Architecture Overview](./index.md) diff --git a/docs/architecture/index.md b/docs/architecture/index.md new file mode 100644 index 0000000..7def2e0 --- /dev/null +++ b/docs/architecture/index.md @@ -0,0 +1,181 @@ +# πŸ—οΈ D2X Technical Architecture + +## Core Design Principles + +D2X minimizes complexity by leveraging GitHub's platform features rather than building parallel systems. This approach: + +- Makes enterprise features accessible to everyone +- Reduces security attack surface +- Enables native integration with GitHub's ecosystem +- Simplifies maintenance and updates + +## πŸ” Environment Structure + +The foundation of D2X's security model is GitHub's Environments feature, used in a novel two-stage pattern: + +```mermaid +stateDiagram-v2 + [*] --> BaseEnvironment + state BaseEnvironment { + [*] --> StoreCredential + StoreCredential --> ProtectAccess + ProtectAccess --> WaitForRequest + WaitForRequest --> ExchangeToken + } + + state SessionEnvironment { + [*] --> CreateTemporary + CreateTemporary --> SetTimeLimit + SetTimeLimit --> GrantAccess + GrantAccess --> MonitorUsage + MonitorUsage --> Revoke + } + + BaseEnvironment --> SessionEnvironment: Token Exchange + SessionEnvironment --> [*]: Auto Expire/Revoke +``` + +### Base Environment + +- Stores long-lived org credentials (SFDX auth URLs) +- Implements protection rules and approvals +- Handles token exchange requests +- Maintains audit logs + +### Session Environment + +- Contains temporary access tokens +- Auto-expires after configured time +- Can be instantly revoked +- Scoped to specific jobs/workflows + +[Learn more about environment configuration](./architecture/environments.md) + +## πŸ“¦ Repository Architecture + +D2X uses GitHub's repository features to represent Salesforce orgs and their relationships: + +```mermaid +flowchart TB + subgraph "Repository Structure" + direction TB + BaseRepo["Base Repository Template"] + OrgRepo["Org-Specific Repository"] + TeamFork["Team Fork"] + + subgraph "Repository Components" + Config["cumulusci.yml"] + Workflows[".github/workflows"] + Source["force-app/"] + Scripts["scripts/"] + end + + subgraph "Branch Protection" + Reviews["Required Reviews"] + Checks["Status Checks"] + Scans["Security Scans"] + end + + BaseRepo -->|"Create"| OrgRepo + OrgRepo -->|"Fork"| TeamFork + TeamFork -->|"PR"| OrgRepo + + Config --> Checks + Workflows --> Checks + Scans -->|"Gate"| Reviews + end +``` + +### Repository Types + +- Base templates for different org patterns +- Org-specific repositories (forked from templates) +- Team forks for development + +### Security Features + +- Branch protection rules +- Required status checks +- Automated security scanning +- Pull request reviews + +[Learn more about repository features](./architecture/repositories.md) + +## ⚑ Actions & Workflows + +D2X provides reusable workflows that leverage GitHub Actions: + +```mermaid +flowchart TB + subgraph "Workflow Components" + subgraph "Security Layer" + Auth["Authentication"] + Session["Session Management"] + Secrets["Secret Handling"] + end + + subgraph "Core Operations" + Deploy["Deployment"] + Test["Testing"] + Validate["Validation"] + end + + subgraph "Integration Layer" + SFDX["SFDX Bridge"] + CCI["CumulusCI Bridge"] + External["External Services"] + end + + Auth --> Session + Session --> Core["Core Operations"] + Core --> Integration["Integration Layer"] + end +``` + +### Composable Design + +Each workflow is built from smaller, reusable components that can be: + +- Combined in different ways +- Customized as needed +- Versioned independently +- Shared across repositories + +[Learn more about workflow patterns](./architecture/workflows.md) + +## πŸ”Œ Integration Points + +D2X bridges GitHub with your existing tools and processes: + +```mermaid +flowchart LR + subgraph "GitHub Platform" + Actions["GitHub Actions"] + Environments["Environments"] + Secrets["Secrets"] + end + + subgraph "Development Tools" + SFDX["SFDX"] + CCI["CumulusCI"] + VS["VS Code"] + end + + subgraph "External Systems" + ITSM["ITSM Tools"] + CI["CI Systems"] + Deploy["Deployment Tools"] + end + + GitHub --> Development + GitHub --> External +``` + +### Native Integrations + +- Seamless SFDX/CumulusCI usage +- ITSM system connections +- CI/CD tool bridges +- Deployment frameworks + +[Learn more about integrations](./architecture/integrations.md) diff --git a/docs/architecture/integrations.md b/docs/architecture/integrations.md new file mode 100644 index 0000000..b38e799 --- /dev/null +++ b/docs/architecture/integrations.md @@ -0,0 +1,38 @@ +# Integration Points + +## Native Integrations + +D2X bridges GitHub with your existing tools and processes: + +```mermaid +flowchart LR + subgraph "GitHub Platform" + Actions["GitHub Actions"] + Environments["Environments"] + Secrets["Secrets"] + end + + subgraph "Development Tools" + SFDX["SFDX"] + CCI["CumulusCI"] + VS["VS Code"] + end + + subgraph "External Systems" + ITSM["ITSM Tools"] + CI["CI Systems"] + Deploy["Deployment Tools"] + end + + GitHub --> Development + GitHub --> External +``` + +### Native Integrations + +- Seamless SFDX/CumulusCI usage +- ITSM system connections +- CI/CD tool bridges +- Deployment frameworks + +[Back to Architecture Overview](./index.md) diff --git a/docs/architecture/repositories.md b/docs/architecture/repositories.md new file mode 100644 index 0000000..703032c --- /dev/null +++ b/docs/architecture/repositories.md @@ -0,0 +1,35 @@ +# Repository Features + +## Repository Types + +### Base Templates + +D2X provides base templates for different org patterns. These templates serve as the foundation for creating org-specific repositories. + +### Org-Specific Repositories + +Org-specific repositories are forked from the base templates. They represent individual Salesforce orgs and their configurations. + +### Team Forks + +Team forks are created from org-specific repositories. They are used for development and collaboration within teams. + +## Security Features + +### Branch Protection Rules + +D2X enforces branch protection rules to ensure code quality and security. These rules include required status checks and pull request reviews. + +### Required Status Checks + +Before merging a pull request, D2X requires that all status checks pass. This ensures that the code meets the necessary quality standards. + +### Automated Security Scanning + +D2X integrates automated security scanning to identify and fix vulnerabilities in the codebase. This helps maintain a secure and compliant environment. + +### Pull Request Reviews + +D2X enforces pull request reviews to ensure that code changes are reviewed by team members before being merged. This helps maintain code quality and collaboration. + +[Back to Architecture Overview](./index.md) diff --git a/docs/architecture/security.md b/docs/architecture/security.md new file mode 100644 index 0000000..d6e3a7c --- /dev/null +++ b/docs/architecture/security.md @@ -0,0 +1,53 @@ +# πŸ” Security Architecture + +## Security Layers + +D2X's security architecture is built on multiple layers to ensure the highest level of protection for your Salesforce orgs and data. + +### 1. Authentication and Authorization + +- **GitHub Environments**: Use GitHub Environments to manage long-term credentials and temporary access tokens. +- **Two-Stage Authentication**: Implement a two-stage authentication process to separate long-term credentials from temporary access tokens. +- **Role-Based Access Control**: Define roles and permissions to control access to sensitive data and operations. + +### 2. Data Protection + +- **Encryption**: Encrypt sensitive data both at rest and in transit. +- **Data Masking**: Use data masking techniques to protect sensitive information in non-production environments. +- **Backup and Recovery**: Implement regular backup and recovery processes to ensure data integrity and availability. + +### 3. Network Security + +- **Firewall Rules**: Define and enforce firewall rules to restrict access to your Salesforce orgs. +- **VPN**: Use Virtual Private Networks (VPN) to secure communication between your on-premises systems and Salesforce. +- **IP Whitelisting**: Restrict access to your Salesforce orgs based on IP addresses. + +### 4. Monitoring and Auditing + +- **Audit Logs**: Maintain detailed audit logs for all access and operations. +- **Security Monitoring**: Implement security monitoring tools to detect and respond to potential threats. +- **Compliance Reporting**: Generate compliance reports to meet regulatory requirements. + +## Protection Rules + +D2X leverages GitHub's protection rules to enforce security policies and ensure compliance. + +### 1. Branch Protection + +- **Required Reviews**: Enforce required reviews for all pull requests. +- **Status Checks**: Require status checks to pass before merging pull requests. +- **Code Scanning**: Automatically scan code for vulnerabilities before merging. + +### 2. Secret Management + +- **Secret Scanning**: Automatically scan for secrets in your codebase. +- **Secret Rotation**: Implement regular secret rotation to minimize the risk of exposure. +- **Access Controls**: Define access controls to restrict who can view and use secrets. + +### 3. Automated Security Workflows + +- **Security Checks**: Implement automated security checks in your CI/CD pipelines. +- **Vulnerability Management**: Automatically detect and remediate vulnerabilities in your dependencies. +- **Incident Response**: Define and automate incident response workflows to quickly address security incidents. + +[Back to Architecture Overview](./index.md) diff --git a/docs/architecture/workflows.md b/docs/architecture/workflows.md new file mode 100644 index 0000000..17ec982 --- /dev/null +++ b/docs/architecture/workflows.md @@ -0,0 +1,102 @@ +# Workflow Patterns + +## Composable Design + +D2X workflows are built from smaller, reusable components that can be: + +- Combined in different ways +- Customized as needed +- Versioned independently +- Shared across repositories + +## Integration Layer + +D2X bridges GitHub with your existing tools and processes: + +```mermaid +flowchart LR + subgraph "GitHub Platform" + Actions["GitHub Actions"] + Environments["Environments"] + Secrets["Secrets"] + end + + subgraph "Development Tools" + SFDX["SFDX"] + CCI["CumulusCI"] + VS["VS Code"] + end + + subgraph "External Systems" + ITSM["ITSM Tools"] + CI["CI Systems"] + Deploy["Deployment Tools"] + end + + GitHub --> Development + GitHub --> External +``` + +### Native Integrations + +- Seamless SFDX/CumulusCI usage +- ITSM system connections +- CI/CD tool bridges +- Deployment frameworks + +## Modular Workflows and Reusable Jobs + +D2X now includes a set of modular workflows and reusable jobs to streamline and standardize common tasks. These workflows are designed to be configurable and reusable, making it easier to manage and maintain your CI/CD processes. + +### New Modular Workflows + +1. **Check No Org Workflow** + - File: `.github/workflows/check-no-org.yml` + - Description: Checks anything that doesn't require an org. + - Configuration: No specific configuration required. + +2. **Create Feature Test Package Workflow** + - File: `.github/workflows/create-feature-test-package.yml` + - Description: Creates the feature test package. + - Configuration: No specific configuration required. + +3. **Create Test Scratch Org Workflow** + - File: `.github/workflows/create-test-scratch-org.yml` + - Description: Creates the test scratch org and its environment using d2x commands. + - Configuration: No specific configuration required. + +4. **Configure Org for Testing Workflow** + - File: `.github/workflows/configure-org-for-testing.yml` + - Description: Configures the org for testing by running `cci flow run ci_feature_2gp --skip-from run-tests`. + - Configuration: No specific configuration required. + +5. **Run Tests Workflow** + - File: `.github/workflows/run-tests.yml` + - Description: Runs the tests by executing `cci flow run ci_feature_2gp --start-from`. + - Configuration: No specific configuration required. + +6. **Dispose Org Workflow** + - File: `.github/workflows/dispose-org.yml` + - Description: Disposes of the org with options for keeping the org based on conditions and snapshotting the org using CumulusCI. + - Configuration: No specific configuration required. + +7. **Create Org Workflow** + - File: `.github/workflows/create-org.yml` + - Description: Creates orgs using a scratchdef path, CLI options, or a CumulusCI scratch profile name, and runs against a DevHub environment with `D2X_SF_ROLE=devhub-scratch`. + - Configuration: No specific configuration required. + +### Reusable Jobs + +1. **Check Conditions Job** + - Description: Checks conditions for various workflows. + - Configuration: No specific configuration required. + +2. **Set Default Org Job** + - Description: Sets the default org for various workflows. + - Configuration: No specific configuration required. + +3. **Capture Build History Job** + - Description: Captures the build history for various workflows. + - Configuration: No specific configuration required. + +[Back to Architecture Overview](./index.md) diff --git a/docs/audiences/enterprise.md b/docs/audiences/enterprise.md new file mode 100644 index 0000000..0bbf64d --- /dev/null +++ b/docs/audiences/enterprise.md @@ -0,0 +1,64 @@ +# 🏒 Enterprise Organizations + +## Use Cases + +### 1. Large-Scale Deployments + +Enterprise organizations often manage multiple Salesforce instances across different regions and departments. D2X provides a unified platform to manage these deployments efficiently. + +- **Centralized Management**: Manage all Salesforce instances from a single platform. +- **Automated Deployments**: Use GitHub Actions to automate deployments across multiple instances. +- **Compliance and Security**: Ensure all deployments meet compliance and security standards. + +### 2. Integration with Existing ITSM Systems + +Enterprises typically use IT Service Management (ITSM) systems like ServiceNow or Jira. D2X integrates seamlessly with these systems to streamline change management processes. + +- **Change Requests**: Automatically create change requests in ITSM systems for deployments. +- **Approval Workflows**: Integrate approval workflows with ITSM systems. +- **Audit Trails**: Maintain detailed audit trails for all changes. + +### 3. Custom Development and Extensions + +Enterprises often require custom development and extensions to meet their unique business needs. D2X supports custom development workflows. + +- **Custom Workflows**: Create custom workflows for development and deployment. +- **Reusable Components**: Build reusable components to speed up development. +- **Version Control**: Use GitHub for version control and collaboration. + +## Value Proposition + +### 1. Enhanced Security + +D2X leverages GitHub's advanced security features to provide enterprise-grade security. + +- **Secret Scanning**: Automatically scan for secrets in your codebase. +- **Code Scanning**: Identify and fix vulnerabilities in your code. +- **Dependency Management**: Manage dependencies securely. + +### 2. Improved Efficiency + +Automate repetitive tasks and streamline workflows to improve efficiency. + +- **Automated Testing**: Use GitHub Actions to automate testing. +- **Continuous Integration**: Implement continuous integration and continuous deployment (CI/CD) pipelines. +- **Monitoring and Alerts**: Set up monitoring and alerts for deployments. + +### 3. Scalability + +D2X is designed to scale with your organization. + +- **Scalable Architecture**: Built on GitHub's scalable architecture. +- **Flexible Workflows**: Create flexible workflows to meet your organization's needs. +- **Global Reach**: Manage deployments across multiple regions and departments. + +## Getting Started + +To get started with D2X for your enterprise organization, follow these steps: + +1. **Set Up GitHub**: Create a GitHub organization and repositories for your Salesforce instances. +2. **Configure D2X**: Configure D2X to manage your Salesforce instances. +3. **Integrate ITSM**: Integrate D2X with your existing ITSM systems. +4. **Automate Workflows**: Create and automate workflows for development, testing, and deployment. + +For detailed instructions, refer to the [D2X Documentation](../index.md). diff --git a/docs/audiences/index.md b/docs/audiences/index.md new file mode 100644 index 0000000..1f3e2b0 --- /dev/null +++ b/docs/audiences/index.md @@ -0,0 +1,227 @@ +# 🌐 D2X: DevOps for the Entire Salesforce Ecosystem + +## Why One Solution Matters + +The Salesforce ecosystem is diverse, from nonprofits leveraging NPSP to Fortune 500 enterprises managing complex global implementations. Traditional DevOps solutions force these different audiences to choose between oversimplified tools that don't scale, or complex platforms that require significant investment in both cost and expertise. + +D2X is the first Salesforce DevOps solution built to serve the entire ecosystem through three core principles: + +- 🎯 **Easy**: Start with simple workflows, grow when ready +- ⚑ **Efficient**: Automate everything that should be automated +- πŸ”§ **Extensible**: Build on proven patterns, customize when needed + +## 🏒 Enterprise Organizations + +Enterprise Salesforce implementations demand enterprise-grade solutions. D2X integrates seamlessly with existing ITSM systems while providing the security and compliance features large organizations require. + +```mermaid +flowchart TB + subgraph "Enterprise Org Management" + subgraph "GitHub Platform" + ProdEnv["πŸ” Production Environment"] + UATEnv["UAT Environment"] + DevEnv["Dev Environment"] + + subgraph "Security" + SecretScan["Secret Scanning"] + GHAS["Advanced Security"] + Audit["Audit Logs"] + end + + subgraph "Automation" + Actions["GitHub Actions"] + Workflows["Reusable Workflows"] + end + end + + subgraph "ITSM Integration" + SN["ServiceNow"] + Jira["Jira"] + ITSM["Other ITSM"] + end + + subgraph "Salesforce Orgs" + PROD["Production"] + UAT["UAT Sandboxes"] + DEV["Dev Sandboxes"] + SCRATCH["Scratch Orgs"] + end + + ProdEnv -->|"Gated Deploy"| PROD + UATEnv -->|"Deploy"| UAT + DevEnv -->|"Deploy"| DEV + Actions -->|"Create"| SCRATCH + + SN -.->|"Change Request"| ProdEnv + Jira -.->|"Tickets"| Actions + ITSM -.->|"Approvals"| ProdEnv + end +``` + +### Security & Compliance That Scales + +The two-stage credential management system provides enterprise-grade security while simplifying access management. By leveraging GitHub's Advanced Security features, D2X enables: + +- Automated secret scanning and rotation +- Comprehensive audit trails +- Compliance reporting +- Role-based access control + +[Learn more about enterprise features](./enterprise.md) + +## πŸ“¦ ISVs & Package Developers + +For ISVs, speed and reliability in package development directly impacts revenue. D2X streamlines the entire development lifecycle while meeting AppExchange security requirements. + +```mermaid +flowchart TB + subgraph "ISV Package Development & Customer Management" + subgraph "GitHub Organization" + direction TB + ProductRepo["πŸ“¦ Product Repository"] + BaseCustomer["Base Customer Repository"] + Customer1["Customer A Repository"] + Customer2["Customer B Repository"] + Customer3["Customer C Repository"] + + ProductRepo -->|"Template"| BaseCustomer + BaseCustomer -->|"Fork"| Customer1 + BaseCustomer -->|"Fork"| Customer2 + BaseCustomer -->|"Fork"| Customer3 + end + + subgraph "Package Development" + DevHub["DevHub"] + PackageOrg["Packaging Org"] + ProdScratch["Product Scratch Orgs"] + + ProductRepo -->|"Create"| ProdScratch + ProductRepo -->|"Package"| PackageOrg + end + + subgraph "Customer Orgs" + Cust1Prod["Customer A Production"] + Cust1Sand["Customer A Sandboxes"] + Cust2Prod["Customer B Production"] + Cust2Sand["Customer B Sandboxes"] + + Customer1 -->|"Deploy"| Cust1Prod + Customer1 -->|"Deploy"| Cust1Sand + Customer2 -->|"Deploy"| Cust2Prod + Customer2 -->|"Deploy"| Cust2Sand + end + end +``` + +### Optimized Package Development + +D2X's composable automation approach means ISVs can build once, reuse everywhere: + +- Automated scratch org creation and setup +- Standardized security review preparation +- Streamlined customer org deployments + +For ISVs, and potentially for other partners, there's a huge potential to build custom setup UX into their package and trigger GitHub Actions workflows to get an OAuth connection to the target org and run automation with configuration passed via JSON in the UX. + +[Learn more about ISV features](./isv.md) + +## 🀝 Consulting Partners + +System Integrators face the unique challenge of managing multiple clients with different needs. D2X's composable approach turns repeated patterns into reusable assets. + +```mermaid +flowchart TB + subgraph "SI Partner Collaboration Model" + subgraph "GitHub Security" + PartnerOrg["Partner GitHub Organization"] + ClientEnv["Client-Specific Environments"] + SecretStore["πŸ” Credential Management"] + end + + subgraph "Development Teams" + Partners["Partner Teams"] + Clients["Client Teams"] + Reviews["Code Reviews"] + end + + subgraph "Client Orgs" + Prod["Production Orgs"] + Sand["Sandboxes"] + Scratch["Scratch Orgs"] + end + + PartnerOrg -->|"Secure Access"| SecretStore + SecretStore -->|"Temporary Credentials"| Partners + Partners -->|"Submit"| Reviews + Clients -->|"Approve"| Reviews + Reviews -->|"Deploy"| Prod + Reviews -->|"Deploy"| Sand + Partners -->|"Create"| Scratch + end +``` + +### Template-Based Efficiency + +Start with proven patterns and customize for each client's needs: + +- Standardized project templates +- Secure credential management +- Client-specific customizations +- Knowledge transfer automation + +[Learn more about partner features](./partner.md) + +## 🌱 Small Teams & Nonprofits + +With GitHub's free offering for nonprofits, D2X makes enterprise-grade DevOps accessible to everyone. Start simple and grow as needed. + +```mermaid +flowchart TB + subgraph "Nonprofit Automation" + subgraph "GitHub Free" + NPSPFlow["NPSP Update Workflows"] + AutoFlow["Automation Workflows"] + SecureEnv["πŸ” Secure Environments"] + end + + subgraph "Automated Tasks" + SandboxRefresh["Sandbox Refresh"] + DataMask["Data Masking"] + TestData["Test Data Load"] + Config["Config Updates"] + end + + subgraph "Salesforce Orgs" + Prod["Production"] + Sand["Sandbox"] + NPSP["NPSP Updates"] + end + + NPSPFlow -->|"Auto Update"| NPSP + AutoFlow -->|"Automate"| SandboxRefresh + SandboxRefresh -->|"Refresh"| Sand + AutoFlow -->|"Run"| DataMask + AutoFlow -->|"Load"| TestData + SecureEnv -->|"Secure Access"| Prod + end +``` + +### Start Where You Are + +D2X grows with your team: + +- Simple GitHub-based workflows +- Pre-built NPSP integration +- Secure by default +- Clear upgrade paths + +[Learn more about nonprofit features](./nonprofit.md) + +## 🎯 Choose Your Path + +Every organization's DevOps journey is different. Select your starting point: + +- [Enterprise Guide](./guides/enterprise-start.md) +- [ISV Guide](./guides/isv-start.md) +- [Partner Guide](./guides/partner-start.md) +- [Small Team Guide](./guides/small-team-start.md) diff --git a/docs/audiences/isv.md b/docs/audiences/isv.md new file mode 100644 index 0000000..69f906b --- /dev/null +++ b/docs/audiences/isv.md @@ -0,0 +1,68 @@ +# πŸ“¦ ISVs & Package Developers + +## Use Cases + +### 1. Accelerated Package Development + +Independent Software Vendors (ISVs) and package developers need to deliver high-quality packages quickly. D2X provides tools and workflows to streamline the development process. + +- **Automated Testing**: Use GitHub Actions to automate testing of your packages. +- **Continuous Integration**: Implement CI/CD pipelines to ensure code quality. +- **Version Control**: Manage your package versions with GitHub. + +### 2. Customer-Specific Customizations + +ISVs often need to customize their packages for different customers. D2X supports customer-specific customizations. + +- **Forking Repositories**: Create customer-specific forks of your package repository. +- **Custom Workflows**: Implement custom workflows for different customers. +- **Automated Deployments**: Use GitHub Actions to automate deployments to customer orgs. + +### 3. Security and Compliance + +Meeting AppExchange security requirements is crucial for ISVs. D2X helps you meet these requirements. + +- **Code Scanning**: Automatically scan your code for vulnerabilities. +- **Secret Management**: Securely manage secrets and credentials. +- **Audit Trails**: Maintain detailed audit trails for all changes. + +### 4. Custom Setup UX and GitHub Actions Workflows + +For ISVs, and potentially for other partners, there's a huge potential to build custom setup UX into their package and trigger GitHub Actions workflows to get an OAuth connection to the target org and run automation with configuration passed via JSON in the UX. + +## Value Proposition + +### 1. Increased Productivity + +D2X automates repetitive tasks, allowing developers to focus on building features. + +- **Automated Testing**: Reduce the time spent on manual testing. +- **Continuous Integration**: Catch issues early with automated CI/CD pipelines. +- **Reusable Components**: Build reusable components to speed up development. + +### 2. Enhanced Security + +D2X leverages GitHub's security features to protect your code and data. + +- **Secret Scanning**: Automatically scan for secrets in your codebase. +- **Code Scanning**: Identify and fix vulnerabilities in your code. +- **Dependency Management**: Manage dependencies securely. + +### 3. Improved Customer Satisfaction + +Deliver high-quality packages and customizations to your customers quickly and reliably. + +- **Automated Deployments**: Ensure consistent deployments to customer orgs. +- **Custom Workflows**: Tailor workflows to meet customer-specific needs. +- **Detailed Audit Trails**: Provide customers with detailed audit trails for all changes. + +## Getting Started + +To get started with D2X for your ISV or package development, follow these steps: + +1. **Set Up GitHub**: Create a GitHub organization and repositories for your packages. +2. **Configure D2X**: Configure D2X to manage your package development and deployments. +3. **Automate Workflows**: Create and automate workflows for development, testing, and deployment. +4. **Ensure Security**: Implement security best practices using D2X and GitHub's security features. + +For detailed instructions, refer to the [D2X Documentation](../index.md). diff --git a/docs/audiences/nonprofit.md b/docs/audiences/nonprofit.md new file mode 100644 index 0000000..4bf0627 --- /dev/null +++ b/docs/audiences/nonprofit.md @@ -0,0 +1,55 @@ +# 🌱 Nonprofit Organizations + +## Use Cases + +### 1. Cost-Effective DevOps + +Nonprofit organizations often operate with limited budgets. D2X provides a cost-effective DevOps solution that leverages GitHub's free offerings for nonprofits. + +- **Free GitHub Access**: Utilize GitHub's free plan for nonprofits. +- **Automated Workflows**: Use GitHub Actions to automate repetitive tasks. +- **Scalable Solutions**: Start small and scale as needed. + +### 2. Simplified Management + +Managing Salesforce instances can be complex. D2X simplifies this process for nonprofits. + +- **Centralized Management**: Manage all Salesforce instances from a single platform. +- **Automated Deployments**: Use GitHub Actions to automate deployments. +- **Compliance and Security**: Ensure all deployments meet compliance and security standards. + +### 3. Pre-Built Integrations + +D2X comes with pre-built integrations for common nonprofit use cases, such as the Nonprofit Success Pack (NPSP). + +- **NPSP Integration**: Seamlessly integrate with the Nonprofit Success Pack. +- **Data Management**: Automate data management tasks. +- **Reporting and Analytics**: Generate reports and analytics to track progress. + +## Value Proposition + +### 1. Accessibility + +D2X makes enterprise-grade DevOps accessible to nonprofits. + +- **Free GitHub Access**: Leverage GitHub's free plan for nonprofits. +- **User-Friendly Interface**: Easy-to-use interface for managing Salesforce instances. +- **Community Support**: Access to a community of users and developers. + +### 2. Efficiency + +Automate repetitive tasks and streamline workflows to improve efficiency. + +- **Automated Testing**: Use GitHub Actions to automate testing. +- **Continuous Integration**: Implement continuous integration and continuous deployment (CI/CD) pipelines. +- **Monitoring and Alerts**: Set up monitoring and alerts for deployments. + +### 3. Scalability + +D2X is designed to scale with your organization. + +- **Scalable Architecture**: Built on GitHub's scalable architecture. +- **Flexible Workflows**: Create flexible workflows to meet your organization's needs. +- **Global Reach**: Manage deployments across multiple regions and departments. + +[Back to Audiences Overview](./index.md) diff --git a/docs/audiences/partner.md b/docs/audiences/partner.md new file mode 100644 index 0000000..9d88e35 --- /dev/null +++ b/docs/audiences/partner.md @@ -0,0 +1,64 @@ +# 🀝 Consulting Partners + +## Use Cases + +### 1. Multi-Client Management + +Consulting partners often manage multiple clients with different Salesforce instances. D2X provides a unified platform to manage these clients efficiently. + +- **Centralized Management**: Manage all client Salesforce instances from a single platform. +- **Automated Deployments**: Use GitHub Actions to automate deployments across multiple client instances. +- **Compliance and Security**: Ensure all deployments meet compliance and security standards. + +### 2. Custom Development and Extensions + +Consulting partners often require custom development and extensions to meet their clients' unique business needs. D2X supports custom development workflows. + +- **Custom Workflows**: Create custom workflows for development and deployment. +- **Reusable Components**: Build reusable components to speed up development. +- **Version Control**: Use GitHub for version control and collaboration. + +### 3. Integration with Client Systems + +Consulting partners typically need to integrate with their clients' existing systems. D2X integrates seamlessly with these systems to streamline processes. + +- **Change Requests**: Automatically create change requests in client systems for deployments. +- **Approval Workflows**: Integrate approval workflows with client systems. +- **Audit Trails**: Maintain detailed audit trails for all changes. + +## Value Proposition + +### 1. Enhanced Security + +D2X leverages GitHub's advanced security features to provide enterprise-grade security. + +- **Secret Scanning**: Automatically scan for secrets in your codebase. +- **Code Scanning**: Identify and fix vulnerabilities in your code. +- **Dependency Management**: Manage dependencies securely. + +### 2. Improved Efficiency + +Automate repetitive tasks and streamline workflows to improve efficiency. + +- **Automated Testing**: Use GitHub Actions to automate testing. +- **Continuous Integration**: Implement continuous integration and continuous deployment (CI/CD) pipelines. +- **Monitoring and Alerts**: Set up monitoring and alerts for deployments. + +### 3. Scalability + +D2X is designed to scale with your organization. + +- **Scalable Architecture**: Built on GitHub's scalable architecture. +- **Flexible Workflows**: Create flexible workflows to meet your organization's needs. +- **Global Reach**: Manage deployments across multiple regions and departments. + +## Getting Started + +To get started with D2X for your consulting practice, follow these steps: + +1. **Set Up GitHub**: Create a GitHub organization and repositories for your clients' Salesforce instances. +2. **Configure D2X**: Configure D2X to manage your clients' Salesforce instances. +3. **Integrate Client Systems**: Integrate D2X with your clients' existing systems. +4. **Automate Workflows**: Create and automate workflows for development, testing, and deployment. + +For detailed instructions, refer to the [D2X Documentation](../index.md). diff --git a/docs/audiences/small.md b/docs/audiences/small.md new file mode 100644 index 0000000..67fa0cd --- /dev/null +++ b/docs/audiences/small.md @@ -0,0 +1,64 @@ +# 🌱 Small Teams & Nonprofits + +## Use Cases + +### 1. Cost-Effective DevOps + +Small teams and nonprofits often operate with limited budgets. D2X provides a cost-effective DevOps solution that leverages GitHub's free offerings for nonprofits. + +- **Free GitHub Access**: Utilize GitHub's free plan for nonprofits. +- **Automated Workflows**: Use GitHub Actions to automate repetitive tasks. +- **Scalable Solutions**: Start small and scale as needed. + +### 2. Simplified Management + +Managing Salesforce instances can be complex. D2X simplifies this process for small teams and nonprofits. + +- **Centralized Management**: Manage all Salesforce instances from a single platform. +- **Automated Deployments**: Use GitHub Actions to automate deployments. +- **Compliance and Security**: Ensure all deployments meet compliance and security standards. + +### 3. Pre-Built Integrations + +D2X comes with pre-built integrations for common nonprofit use cases, such as the Nonprofit Success Pack (NPSP). + +- **NPSP Integration**: Seamlessly integrate with the Nonprofit Success Pack. +- **Data Management**: Automate data management tasks. +- **Reporting and Analytics**: Generate reports and analytics to track progress. + +## Value Proposition + +### 1. Accessibility + +D2X makes enterprise-grade DevOps accessible to small teams and nonprofits. + +- **Free GitHub Access**: Leverage GitHub's free plan for nonprofits. +- **User-Friendly Interface**: Easy-to-use interface for managing Salesforce instances. +- **Community Support**: Access to a community of users and developers. + +### 2. Efficiency + +Automate repetitive tasks and streamline workflows to improve efficiency. + +- **Automated Testing**: Use GitHub Actions to automate testing. +- **Continuous Integration**: Implement continuous integration and continuous deployment (CI/CD) pipelines. +- **Monitoring and Alerts**: Set up monitoring and alerts for deployments. + +### 3. Scalability + +D2X is designed to scale with your organization. + +- **Scalable Architecture**: Built on GitHub's scalable architecture. +- **Flexible Workflows**: Create flexible workflows to meet your organization's needs. +- **Global Reach**: Manage deployments across multiple regions and departments. + +## Getting Started + +To get started with D2X for your small team or nonprofit, follow these steps: + +1. **Set Up GitHub**: Create a GitHub organization and repositories for your Salesforce instances. +2. **Configure D2X**: Configure D2X to manage your Salesforce instances. +3. **Integrate NPSP**: Integrate D2X with the Nonprofit Success Pack (NPSP). +4. **Automate Workflows**: Create and automate workflows for development, testing, and deployment. + +For detailed instructions, refer to the [D2X Documentation](../index.md). diff --git a/docs/community/index.md b/docs/community/index.md new file mode 100644 index 0000000..65253e5 --- /dev/null +++ b/docs/community/index.md @@ -0,0 +1,40 @@ +# 🀝 Community + +## Open Source at Heart + +D2X is built in the open, leveraging GitHub's collaboration features to create a vibrant ecosystem where everyone benefits. + +```mermaid +flowchart TB + subgraph "Community Ecosystem" + Core["Core Project"] + Extensions["Extensions"] + Templates["Templates"] + Docs["Documentation"] + + Core -->|"Inspire"| Extensions + Core -->|"Share"| Templates + Community -->|"Contribute"| Core + Community -->|"Improve"| Docs + end +``` + +## Ways to Contribute + +- πŸ’‘ Share ideas in Discussions +- πŸ› Report issues +- πŸ”€ Submit pull requests +- πŸ“š Improve documentation + +## Getting Help + +- πŸ“– Documentation +- πŸ’¬ Community discussions +- πŸŽ“ Learning resources +- πŸ‘₯ User groups + +[Join the community on GitHub](https://github.com/muselab-d2x/d2x/discussions) + +## Looking Forward + +Together, we're building a future where secure, scalable Salesforce DevOps is accessible to everyone. Whether you're managing a single org or hundreds, your experience and ideas can help shape this future. diff --git a/docs/cumulusci-next.md b/docs/cumulusci-next.md new file mode 100644 index 0000000..88784b9 --- /dev/null +++ b/docs/cumulusci-next.md @@ -0,0 +1,162 @@ +# D2X cumulusci-next + +## Overview + +D2X [muselab-d2x/d2x@cumulusci-next](https://github.com/muselab-d2x/d2x/tree/cumulusci-next) branch contains a set of precontribution enhancements to CumulusCI we've encountered the need for in our consulting engagements. The end goal is to get all of these contributed back to CumulusCI. But, for now, the `cumulusci-next` branch and Docker image tag of D2X provides the following additional CumulusCI features: + +- Scratch Org Snapshot Management (new) +- Package Version Naming with templated Jinja2 expressions +- Support for looking up 2gp feature test package commit statuses on parent branches +- A simple plugin framework for CumulusCI +- The ability to load arbitrary YAML + +All these features are merged into [muselab-d2x/CumulusCI@d2x](https://github.com/muselab-d2x/CumulusCI) + +The documentation below should all be assumed to apply to the `cumulusci-next` branch, using the `muselab-d2x/CumulusCI` fork as CumulusCI's codebase for now. Eventually the goal is to migrate these into the main branch when they are released in CumulusCI. + +## Scratch Org Snapshot Management with D2X + +D2X uses CumulusCI's `create_snapshot` and `github_pull_request_snapshot` tasks to automate the management of scratch org snapshots for the following uses cases: + +- Maintaining a persistent named snapshot of the project's current dependencies, deployed into an org shape for either unpackaged or packaged deploy/install +- Maintaining a persistent named snapshot of the project's unpackaged code deployed into a non-namespaced scratch org for development +- Maintaining a persistent named snapshot of the project's current release, fully configured with storytelling data, in an org + - Optionally maintain release snapshots for beta/prerelease versions, N+n versions, and past versions +- Maintain an temporary snapshot for the passing or failing build org state of a 2GP Feature Test build on a `feature/` branch + +For more background on the complexities of automating snapshot management for these use cases, check out Muselab's blog post: [Develop, Test, and Fix Faster with Scratch Org Snapshots](https://muselab.com/bench-notes/develop-test-and-fix-faster-with-scratch-org-snapshots) + +The snapshots functionality was generously contributed by [Veruna](https://veruna.com), a Salesforce ISV Partner as part of D2X Transformation Success engagement with [Muselab](https://muselab.com/services). + +### Snapshotting Dependencies + +Coming soon! + +### Snapshotting Unpackaged Source + +Coming soon! NOTE: This will require the ability to deploy into a non-namespaced scratch org. + +### Snapshotting Pull Requests + +The first available reusable workflow for snapshot management is also one of the most valuable because it's designed to be used on every commit to every feature branch! + +D2X's 2GP Feature Test reusable workflow already provides a ton of useful functionality to automate package testing including: + +- Creating a new scratch org using the project's `feature` scratch org definition for CumulusCI +- Creating a new 2GP Feature Test package version of the commit via CumulusCI's built-in `build_feature_test_package` flow + - Uses a separate 2GP package with the same namespace created automatically in the DevHub + - Works with both 1GP and 2GP packages! + - Uses `skipValidation` to create package versions in seconds without requiring a build scratch org + - Read more about this process in Muselab's blog post [3 Approaches to Pre-Release Testing for Salesforce ISVs](https://muselab.com/bench-notes/3-approaches-to-pre-release-testing-for-salesforce-isvs). +- Setting a GitHub Commit Status on the commit, annotating it with description containing the test package version's id, such as `version_id: 04t...` +- Testing the new 2GP Feature Test package version in the build's `feature` scratch org via CumulusCI's built-in `ci_feature_2gp` flow + - Install the 2GP Feature Test package version looked up from the commit status and dependencies using CumulusCI's built-in `install_2gp_commit` flow + - Configure the package with CumulusCI's built-in `config_managed` flow + - Run apex tests with CumulusCI's built-in `run_tests` including GitHub Job Summary reports for test executions +- Delete the build's `feature` scratch org + +That's a lot out of the box. Just enabling this one workflow in your repository is a huge step and an even bigger improvement in productivity and quality if you get it right. + +**So where do Scratch Org Snapshots fit into that workflow?** +With a default limit of 40 Active Snapshots and 40 Daily Snapshots for Enterprise Edition (matching your ActiveScratchOrg limit for both active and daily snapshots), efficient use of snapshots is important. You don't want to snapshot every commit or every branch or you'll likely hit your limits. + +We've worked out what we believe is the ideal workflow for balancing limits and need: + +1. Build every feature branch commit, as before +2. Use Pull Requests to control which branches get snapshots +3. Maintain a snapshot of the HEAD commit on all branches with Pull Requests matching the criteria +4. Use a common naming convention for snapshot names +5. Set the build and commit information in the description field of each OrgSnapshot record +6. Store the shapshot name as a GitHub Commit Status or Check on each commit with a snapshot + +**Quickstart** + +Assuming you already have CumulusCI configured for your project: + +1. Add the new `ci_feature_2gp_pre_snapshot` and `ci_feature_2gp_post_snapshot` flows to allow split execution in the D2X reusable workflow by adding the following to your `cumulusci.yml` file and adapting for any changes your project has made to `ci_feature_2gp`: + +``` +flows: + ci_feature_2gp_pre_snapshot: + description: Pre-snapshot steps for 2gp feature test builds + group: Continuous Integration + steps: + 1: + flow: install_2gp_commit + 2: + flow: config_apextest_managed + + ci_feature_2gp_post_snapshot: + description: Post-snapshot steps for 2gp feature test builds + group: Continuous Integration + steps: + 1: + task: run_tests +``` + +2. Configure the `github_pull_request_snapshot` task's default options in `cumulusci.yml` + +``` +tasks: + github_pull_request_snapshots: + options: + project_code: CI # Customize this!!! + snapshot_pr: True + snapshot_fail_pr: True +``` + +3. Set up the necessary secrets for D2X per the [Tutorial -> Secrets](tutorial.md#secrets) +4. Add the labels `snapshot` and `snapshot-failure` to the repository +5. Add the following file to your repository as `.github/workflows/feature_2gp.yml` + +``` +name: 2GP Feature Test and Snapshot +on: + push: + branches: + - feature/** + - main + workflow_dispatch: + +jobs: + feature-test-and-snapshot: + name: "Feature Test and Snapshot" + uses: muselab-d2x/d2x/.github/workflows/feature-test-2gp-snapshot.yml@cumulusci-next + with: + create_pr_snapshot: true + create_failure_snapshot: true + environment_prefix: "Snapshot: " + commit_status_context: Snapshot + secrets: + dev-hub-auth-url: "${{ secrets.DEV_HUB_AUTH_URL }}" + gh-email: "${{ secrets.GH_EMAIL }}" + github-token: "${{ secrets.GITHUB_TOKEN }}" +``` + +If your project uses CumulusCI's dependencies, you'll want to change the last line to `secrets.CCI_GITHUB_TOKEN`. + +6. Commit to a branch like `feature/d2x-snapshots` and push to GitHub. The build should kick off under the Actions tab. +7. Before the build gets to actually deploying anything, create a Pull Request on the branch and add the `snapshot` and `snapshot-failure` labels to test it out + +**In more detail** +Since building all branches with a Pull Request might also lead to a lot of snapshots, CumulusCI's new `github_pull_request_snapshot` task provides a set of options you configure in your`cumulusci.yml` file: + +NOTE: This task is currently only available in the `d2x@cumulusci-next` Docker image or on GitHub at https://github.com/muselab-d2x/d2x. + +- **project_code**: A 2-character uppercase code for the current project, used as a prefix on all snapshot names. _Must be unique to the DevHub_! +- **snapshot_pr**: Manage snapshots for the `HEAD` commit on branches with a matching Pull Request Default: `True` +- **snapshot_pr_label**: Only match branches with this label on the open Pull Request. Default: `snapshot` +- **snapshot_pr_draft**: Also create snapshots for open draft Pull Requests. Default: `False` +- **snapshot_failure_pr**: Manage snapshots for the latest unresolved build failure of branches with matching open Pull Request. Default: `False` +- **snapshot_failure_pr_label**: Only match branches with this label on the open Pull Request for failure snapshot creation. Default: `snapshot-failure` +- **snapshot_failure_pr_draft**: Also create failure snapshots for branches with an open matching Pull Request. Default: `False` +- **snapshot_failure_test_only**: Only snapshot failures due to test failures. Useful to limit to only prepared orgs with test failures to recreate test failure state. Default: `False` + +There are also a set of options designed to be passed via `cci`: + +- **--wait [True|False]**: If True, polls until the OrgSnapshot has completed and reports the results as one synchronous operation. When set to `False`, reports the InProgress snapshot info and outputs `SNAPSHOT_ID=` to `GITHUB_OUTPUT` if set, allowing future job steps to access the SNAPSHOT_ID to finalize the job with the `--snapshot-id` option. Default: `True` +- **--snapshot_id **: Used for finalizing a snapshots created with `--wait False` to finalize the new snapshot later in the build +- **--build_success [True|False]**: Was the build a success? Default: `True` +- **--build_fail_tests [True|False]**: Did the build fail because of a test failure. Default: `False` +- **--snapshot-is-packaged [True|False]**: Is the source org for the snapshot meant for unpackaged deploys or packaged installs? Default: `False` +- **--commit-status **: If set, sets a GitHub Commit Status or Check with the value as the context and the snapshot name as the value. diff --git a/docs/github/advanced-network-graph.md b/docs/github/advanced-network-graph.md new file mode 100644 index 0000000..b16cdcb --- /dev/null +++ b/docs/github/advanced-network-graph.md @@ -0,0 +1,67 @@ +# 🌐 Advanced Network Graph Features + +## Identifying Potential Issues and Conflicts + +The Network graph in GitHub can be used to identify potential issues and conflicts in the deployment and configuration of modules. By visualizing the relationships between repositories, you can spot areas where changes might conflict or where there might be issues with merging branches. + +```mermaid +flowchart TB + subgraph "Potential Issues" + Repo1["Repository 1"] + Repo2["Repository 2"] + Branch1["Branch 1"] + Branch2["Branch 2"] + Conflict["Conflict Area"] + + Repo1 --> Branch1 + Repo2 --> Branch2 + Branch1 --> Conflict + Branch2 --> Conflict + end +``` + +### Example + +Consider a scenario where multiple teams are working on different forks of a repository. The Network graph can help you identify branches that have diverged significantly and might cause conflicts when merged. By analyzing the graph, you can proactively address these issues before they become problematic. + +## Tips and Best Practices + +Using the Network graph effectively requires some best practices and tips to manage complex repository structures and relationships. + +### Best Practices + +1. **Regularly Review the Graph**: Make it a habit to regularly review the Network graph to stay informed about the state of your repositories. +2. **Communicate with Teams**: Use the insights from the Network graph to communicate with teams about potential issues and coordinate efforts to resolve them. +3. **Merge Frequently**: Encourage teams to merge changes frequently to minimize the risk of conflicts and keep branches up to date. +4. **Use Descriptive Branch Names**: Use descriptive branch names to make it easier to understand the purpose of each branch in the Network graph. + +## Customizing and Extending the Network Graph + +The Network graph in GitHub can be customized and extended to meet specific needs in D2X projects. By leveraging GitHub's API and other tools, you can create custom visualizations and integrations. + +### Custom Visualizations + +You can use GitHub's API to fetch data about the relationships between repositories and create custom visualizations that provide additional insights. For example, you can create a dashboard that shows the status of different branches, highlights potential conflicts, and provides metrics on the health of your repositories. + +```mermaid +flowchart TB + subgraph "Custom Dashboard" + BranchStatus["Branch Status"] + ConflictHighlight["Conflict Highlight"] + Metrics["Repository Metrics"] + + BranchStatus --> Dashboard + ConflictHighlight --> Dashboard + Metrics --> Dashboard + end +``` + +### Integrations + +Integrate the Network graph with other tools and systems to enhance its functionality. For example, you can integrate it with your CI/CD pipeline to automatically update the graph with the latest changes and provide real-time insights into the state of your repositories. + +### Example + +Consider a scenario where you want to create a custom dashboard that shows the status of different branches and highlights potential conflicts. You can use GitHub's API to fetch the necessary data and create a visualization that provides a clear and interactive view of your repository relationships. + +By customizing and extending the Network graph, you can tailor it to meet the specific needs of your D2X projects and gain deeper insights into the state of your repositories. diff --git a/docs/github/index.md b/docs/github/index.md new file mode 100644 index 0000000..db4208f --- /dev/null +++ b/docs/github/index.md @@ -0,0 +1,63 @@ +# βš™οΈ GitHub Platform Features + +D2X leverages GitHub's platform features in novel ways to create a secure, scalable DevOps solution: + +## πŸ—οΈ Core Platform Features + +### Environments + +GitHub Environments become a secure credential vault and access management system: + +```mermaid +flowchart TB + subgraph "GitHub Environments" + Base["Base Environment
Long-term Credentials"] + Session["Session Environment
Temporary Access"] + Protection["Protection Rules
Access Controls"] + + Base -->|"Token Exchange"| Session + Protection -->|"Gates"| Session + end +``` + +### Actions + +Reusable workflows enable composable automation while maintaining security: + +```mermaid +flowchart LR + subgraph "GitHub Actions" + Reusable["Reusable Workflows"] + Composite["Composite Actions"] + Security["Security Checks"] + + Reusable -->|"Compose"| Composite + Security -->|"Gate"| Composite + end +``` + +### Advanced Security + +Native security features protect your entire pipeline: + +- Secret scanning +- Code scanning +- Dependency analysis +- Security policies + +### Repository Features + +From wikis to projects, every feature serves a purpose: + +- Branch protection +- Status checks +- Automated reviews +- Documentation + +### Network Graph + +The Network graph in GitHub is a powerful tool that allows you to visualize the relationships between repositories, including forks and branches. It provides a clear and interactive way to understand how different repositories are connected and how changes flow between them. + +[Learn more about the Network graph](./network-graph.md) + +[Learn more about advanced Network graph features](./advanced-network-graph.md) diff --git a/docs/github/network-graph.md b/docs/github/network-graph.md new file mode 100644 index 0000000..ce65fbc --- /dev/null +++ b/docs/github/network-graph.md @@ -0,0 +1,59 @@ +# 🌐 Network Graph Overview + +## Visualizing Relationships Between Repositories + +The Network graph in GitHub is a powerful tool that allows you to visualize the relationships between repositories, including forks and branches. It provides a clear and interactive way to understand how different repositories are connected and how changes flow between them. + +```mermaid +flowchart TB + subgraph "Repository Relationships" + BaseRepo["Base Repository"] + Fork1["Fork 1"] + Fork2["Fork 2"] + Branch1["Branch 1"] + Branch2["Branch 2"] + + BaseRepo --> Fork1 + BaseRepo --> Fork2 + Fork1 --> Branch1 + Fork2 --> Branch2 + end +``` + +### Example + +Consider a scenario where you have a base repository for a project, and multiple forks of this repository are created by different teams or organizations. The Network graph can help you visualize how these forks are related to the base repository and to each other. It shows the branches within each repository and how changes are merged or diverged. + +## Maintaining a Map of Module Deployment and Configuration + +The Network graph can be particularly useful for maintaining a map of a module's deployment and configuration across different organizations. By visualizing the forks and branches, you can track where and how a module is being deployed, identify which versions are in use, and understand the configuration differences between deployments. + +```mermaid +flowchart TB + subgraph "Module Deployment" + Org1["Organization 1"] + Org2["Organization 2"] + ModuleV1["Module v1"] + ModuleV2["Module v2"] + + Org1 --> ModuleV1 + Org2 --> ModuleV2 + end +``` + +### Example + +Imagine you have a module that is deployed across multiple organizations, each with its own fork of the repository. The Network graph can help you see which organizations are using which versions of the module, and how their configurations differ. This can be invaluable for managing updates, troubleshooting issues, and ensuring consistency across deployments. + +## Accessing and Interpreting the Network Graph + +To access the Network graph in GitHub, navigate to the main page of a repository, click on the "Insights" tab, and then select "Network" from the sidebar. The Network graph will display a visual representation of the repository's forks and branches. + +### Interpreting the Graph + +- **Nodes**: Each node represents a commit in the repository. +- **Lines**: Lines between nodes represent the flow of changes between commits. +- **Branches**: Different branches are shown as separate lines, allowing you to see how they diverge and merge. +- **Forks**: Forks of the repository are displayed as separate lines branching off from the main repository. + +By analyzing the Network graph, you can gain insights into the development history, collaboration patterns, and deployment status of your modules. diff --git a/docs/index.md b/docs/index.md index 77eaafa..e12d6f0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,17 +1,72 @@ -# Introducing D2X +# πŸš€ The Future of D2X: Implementing Salesforce Well-Architected DevOps + +D2X Logo + +## 🎯 The Vision + +The Salesforce [Well-Architected Framework](https://architect.salesforce.com/well-architected/overview) establishes that a truly adaptable solution "evolves with the business" through resilient and composable architecture. As the framework states: + +> "Composable solutions adjust quickly and with greater stability. Composable architectures are built in units that operate gracefully with one another, and can be swapped in and out of service." + +GitHub has built the platform capabilities needed to bring this vision to life. D2X serves as the catalyst that transforms these principles and capabilities into practical, accessible DevOps practices for every Salesforce org. + +## πŸ—οΈ Why GitHub-Native? + +Development teams today are drowning in platforms, credentials, and complexity. As explored in our series on [Securing Salesforce DevOps: Least Privilege Access Control](https://muselab.com/bench-notes/securing-salesforce-devops-least-privilege-access-control), traditional approaches to credential management introduce significant security risks. By building directly on GitHub's platform features, we can eliminate entire categories of security and maintenance concerns while providing a more integrated, intuitive experience. + +## πŸ” Rethinking Security + +The [challenge of securely splitting GitHub Actions workflows](https://muselab.com/bench-notes/securing-salesforce-devops-multi-job-workflows-in-github-actions) showcases why we need a new approach to credential management. The heart of D2X's vision is bringing enterprise-grade security practices to every Salesforce org through GitHub's platform features, aligning with both the [Trusted](https://architect.salesforce.com/well-architected/trusted) principle and the [Application Lifecycle Management](https://architect.salesforce.com/well-architected/adaptable/resilient/application-lifecycle-management) guidance of Well-Architected. + +πŸ” [Learn more about our security architecture](./architecture/security.md) +πŸ”‘ [Learn more about our credential management approach](./architecture/credentials.md) + +## 🧩 Composable Automation + +Following the Well-Architected [Composable](https://architect.salesforce.com/well-architected/adaptable/composable) principle, we're reimagining how automation should work in the Salesforce ecosystem. As outlined in our vision for [The Composable Delivery Model](https://muselab.com/bench-notes/introducing-the-composable-delivery-model), we're breaking everything down into composable pieces that can be mixed and matched to suit any development pattern. + +⚑ The beauty of composable automation is that it scales both up and down: + +- 🏒 Large enterprises can implement complex deployment strategies +- πŸ“¦ ISVs can manage package development and customer deployments +- πŸ‘₯ Small teams can start simple and grow +- 🀝 Nonprofits get pre-built automation for common needs + +πŸ› οΈ [Learn more about our automation architecture](./architecture/automation.md) +πŸ“‹ [Learn more about our workflow patterns](./workflows/index.md) + +## 🌟 For Everyone + +Whether you're a Fortune 500 company, a growing ISV, a small business, or one of the 40,000+ nonprofits running on Salesforce (who can now access all of this for free through GitHub for Nonprofits), D2X is evolving to be your perfect DevOps companion. + +## 🀝 Let's Build Together + +This democratization of Salesforce DevOps is ambitious, but it's the right path forward. By building on GitHub's platform and maintaining our commitment to open source, we can make the Well-Architected vision a reality for everyone. + +Join us in the [GitHub Discussions](https://github.com/muselab-d2x/d2x/discussions) to help shape this future. Whether you're managing a single org or hundreds, your experience and needs matter in building a DevOps solution that truly works for everyone. + +## πŸ—ΊοΈ Explore the Vision + +- [For Different Audiences](./audiences/index.md) +- [Technical Architecture](./architecture/index.md) +- [Workflow Patterns](./workflows/index.md) +- [GitHub Features Utilization](./github/index.md) +- [Community and Support](./community/index.md) + +# Previous Docs: Retained for now... Introducing D2X D2X is an open source collection of tools and configurations to quickly launch and easily maintain Salesforce development projects on GitHub. D2X combines the best of CumulusCI, Salesforce CLI, GitHub Actions, and GitHub Codespaces. D2X projects are set up to align with the Salesforce Well-Architected principle of [Adaptable (Resilient and Composable)](https://architect.salesforce.com/well-architected/adaptable/overview). D2X is made up of: -* A Docker image with the latest versions of CumulusCI and SF CLI preinstalled +- A Docker image with the latest versions of CumulusCI and SF CLI preinstalled + + - GitHub Package: https://github.com/muselab-d2x/d2x/pkgs/container/d2x + - Latest Docker Image: `ghcr.io/muselab-d2x/d2x:latest` - * GitHub Package: https://github.com/muselab-d2x/d2x/pkgs/container/d2x - * Latest Docker Image: `ghcr.io/muselab-d2x/d2x:latest` - -* A set of [reusable GitHub Actions workflows](https://github.com/muselab-d2x/d2x/tree/main/.github/workflows) -* A [devcontainer](https://containers.dev) [configuration](https://github.com/muselab-d2x/d2x/tree/main/.devcontainer) for use with GitHub Codespaces or any IDE with a Devcontainers extension -* A [project template](https://github.com/muselab-d2x/d2x-template) using [cookiecutter](https://cookiecutter.readthedocs.io) +- A set of [reusable GitHub Actions workflows](https://github.com/muselab-d2x/d2x/tree/main/.github/workflows) +- A [devcontainer](https://containers.dev) [configuration](https://github.com/muselab-d2x/d2x/tree/main/.devcontainer) for use with GitHub Codespaces or any IDE with a Devcontainers extension +- A [project template](https://github.com/muselab-d2x/d2x-template) using [cookiecutter](https://cookiecutter.readthedocs.io) D2X is a project of [MuseLab](https://muselab.com) and was created to support our [consulting services](https://muselab.com/services) with Salesforce partners and customers. We proudly share D2X as open source with the Salesforce community as part of our goal to revolutionize and democratize Salesforce DevOps. @@ -25,10 +80,20 @@ You've created your own GitHub repository using [D2X Launchpad](https://launchpa Head over to the [D2X Project Tutorial](tutorial.md) for next steps on finalizing your project's setup and getting started building. +## D2X `cumulusci-next` + +Learn more about advance features of CumulusCI contained in Muselab's preview `cumulusci-next` branch of `d2x` and the corresponding Docker image tag to try out new features like Scratch Org Snapshot management, additional yaml loadable from the command line, a simple plugin framework, and more. + +Check out [D2X cumulusci-next](cumulusci-next.md) for more details. + +## Troubleshooting + +Need help troubleshooting an error? Check out the [Troubleshooting](troubleshooting.md) section for common error messages and tips on debugging issues. + ## Resources D2X itself doesn't require a lot of documentation. It's really about stitching together some amazingly powerful tools. Learning those tools is an important part of learning to work with D2X. The following documentation provides resouces to learn about those tools: -* [CumulusCI Documentation](https://cumulusci.readthedocs.io) -* [Trailhead: Build Applications with CumulusCI](https://trailhead.salesforce.com/content/learn/trails/build-applications-with-cumulusci) -* [Salesforce CLI](https://developer.salesforce.com/tools/salesforcecli) +- [CumulusCI Documentation](https://cumulusci.readthedocs.io) +- [Trailhead: Build Applications with CumulusCI](https://trailhead.salesforce.com/content/learn/trails/build-applications-with-cumulusci) +- [Salesforce CLI](https://developer.salesforce.com/tools/salesforcecli) diff --git a/docs/requirements.txt b/docs/requirements.txt index d9563c9..79b5d86 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,2 +1,3 @@ -mkdocs==1.5.2 -mkdocs_material==9.2.8 +mkdocs==1.6.1 +mkdocs_material==9.5.42 +mkdocs-mermaid2-plugin==1.1.1 diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 0000000..afe2b14 --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,13 @@ +# Troubleshooting D2X + +## Common Errors + +### GitHub Actions + +#### Error: The template is not valid. muselab-d2x/d2x/.github/workflows/feature-test-unlocked.yml@main (Line: 35, Col: 27): Unexpected value '' + +This error can occur when you have a project that uses dependencies and you haven't set up the `CCI_GITHUB_TOKEN` secret for the repository in GitHub or haven't granted the repository permission to an organization level secret. Ensure that the CCI_GITHUB_TOKEN secret is available in the repository under Settings -> Secrets and variables -> Actions. + +#### _In Set Commit Status Step_ gh: Not Found (HTTP 404) + +Check that the GitHub Personal Access Token being used for the `CCI_GITHUB_TOKEN` secret has access to the repository being built. diff --git a/docs/tutorial.md b/docs/tutorial.md index 99172e9..b660bd1 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -18,7 +18,7 @@ To do this, you can use sfdx either on your computer or via Codespaces. **via Codespaces** If you don't already have sfdx installed on your computer and connected to your DevHub, you can [use a Codespace](#launching-a-development-environment) to connect to the DevHub so you can get the sfdxAuthUrl. Simply launch a new Codespace from your D2X project repository then run: sfdx org login device --set-default-dev-hub --alias DevHub -**via sfdx** Assuming you already have sfdx installed on your computer and connected to your DevHub as the alias DevHub, you should be able to get the Sfdx Auth Url (starts with force://) by running sfdx org display -o DevHub --verbose andy copying the auth url (starts with force://, ends with .salesforce.com) +**via sfdx** Assuming you already have sfdx installed on your computer and connected to your DevHub as the alias DevHub, you should be able to get the Sfdx Auth Url (starts with force://) by running sfdx org display -o DevHub --verbose and copying the auth url (starts with force://, ends with .salesforce.com) ## GitHub Token @@ -114,7 +114,7 @@ Add the files, commit the changes, and push the new branch to GitHub: ``` git add force-app/ git commit -m "Added field" -git push --set-upstream-to feature/add-field +git push --set-upstream origin feature/add-field ``` ## Feature Builds diff --git a/docs/workflows/deployment.md b/docs/workflows/deployment.md new file mode 100644 index 0000000..7fcea2f --- /dev/null +++ b/docs/workflows/deployment.md @@ -0,0 +1,70 @@ +# πŸš€ Deployment Patterns + +## Feature Branch Deployment + +Feature branch deployment is a process where changes are deployed to a feature branch for testing and validation before being merged into the main branch. + +### Steps + +1. **Create Feature Branch**: Developers create a new feature branch from the main branch. +2. **Push Changes**: Developers push their changes to the feature branch. +3. **Request Session**: GitHub requests a session from the authentication flow. +4. **Create Scratch Org**: Salesforce creates a scratch org for the feature branch. +5. **Deploy Changes**: GitHub deploys the changes to the scratch org. +6. **Validation Results**: Salesforce returns validation results to GitHub. +7. **Status Update**: GitHub provides a status update to the developer. + +### Diagram + +```mermaid +sequenceDiagram + actor Dev + participant GH as GitHub + participant Auth as Auth Flow + participant SF as Salesforce + + Dev->>GH: Create Feature Branch + Dev->>GH: Push Changes + GH->>Auth: Request Session + Auth->>SF: Create Scratch Org + Auth-->>GH: Return Session + GH->>SF: Deploy Changes + SF-->>GH: Validation Results + GH-->>Dev: Status Update +``` + +## Production Deployment + +Production deployment is the process of deploying changes to the production environment after they have been tested and approved. + +### Steps + +1. **Approve Changes**: Lead approves the changes in the pull request. +2. **Merge to Main**: Pull request is merged into the main branch. +3. **Request Prod Session**: GitHub requests a production session from the authentication flow. +4. **Require Approvals**: Authentication flow requires necessary approvals. +5. **Grant Session**: Authentication flow grants the session after approvals. +6. **Deploy to Production**: GitHub deploys the changes to the production environment. +7. **Deployment Results**: Salesforce returns deployment results to GitHub. + +### Diagram + +```mermaid +sequenceDiagram + actor Lead + participant PR as Pull Request + participant GH as GitHub + participant Auth as Auth Flow + participant SF as Salesforce + + Lead->>PR: Approve Changes + PR->>GH: Merge to Main + GH->>Auth: Request Prod Session + Auth->>GH: Require Approvals + Note over GH: Wait for Required Approvals + Auth-->>GH: Grant Session + GH->>SF: Deploy to Production + SF-->>GH: Deployment Results +``` + +[Back to Workflow Overview](./index.md) diff --git a/docs/workflows/index.md b/docs/workflows/index.md new file mode 100644 index 0000000..8d874d4 --- /dev/null +++ b/docs/workflows/index.md @@ -0,0 +1,176 @@ +# πŸ”§ D2X Workflow Patterns + +## Core Concepts + +D2X workflows are built on two key principles: + +- 🧩 Small, composable pieces that can be mixed and matched +- πŸ” Security-first design with credential isolation + +```mermaid +flowchart TB + subgraph "Workflow Architecture" + subgraph "Security Layer" + Auth["πŸ” Authentication"] + Session["🎫 Session Management"] + end + + subgraph "Core Components" + Validate["βœ… Validation"] + Deploy["πŸš€ Deployment"] + Test["πŸ§ͺ Testing"] + Notify["πŸ“’ Notification"] + end + + subgraph "Outputs" + Results["πŸ“Š Results"] + Logs["πŸ“ Logs"] + Artifacts["πŸ“¦ Artifacts"] + end + + Auth --> Session + Session --> CoreOps["Core Operations"] + CoreOps --> Outputs + end +``` + +## πŸš€ Deployment Patterns + +### Feature Branch Deployment + +```mermaid +sequenceDiagram + actor Dev + participant GH as GitHub + participant Auth as Auth Flow + participant SF as Salesforce + + Dev->>GH: Create Feature Branch + Dev->>GH: Push Changes + GH->>Auth: Request Session + Auth->>SF: Create Scratch Org + Auth-->>GH: Return Session + GH->>SF: Deploy Changes + SF-->>GH: Validation Results + GH-->>Dev: Status Update +``` + +### Production Deployment + +```mermaid +sequenceDiagram + actor Lead + participant PR as Pull Request + participant GH as GitHub + participant Auth as Auth Flow + participant SF as Salesforce + + Lead->>PR: Approve Changes + PR->>GH: Merge to Main + GH->>Auth: Request Prod Session + Auth->>GH: Require Approvals + Note over GH: Wait for Required Approvals + Auth-->>GH: Grant Session + GH->>SF: Deploy to Production + SF-->>GH: Deployment Results +``` + +[Learn more about deployment patterns](./workflows/deployment.md) + +## πŸ§ͺ Testing Frameworks + +D2X provides reusable testing patterns that can be composed into comprehensive test suites: + +```mermaid +flowchart TB + subgraph "Test Framework" + subgraph "Unit Tests" + Apex["Apex Tests"] + LWC["LWC Tests"] + end + + subgraph "Integration Tests" + OrgConfig["Org Configuration"] + DataLoad["Test Data"] + Features["Feature Validation"] + end + + subgraph "User Acceptance" + Sandbox["Sandbox Prep"] + UserFlow["User Flows"] + Validation["Acceptance Criteria"] + end + + Unit["Unit Tests"] --> Integration["Integration Tests"] + Integration --> UAT["User Acceptance"] + UAT --> Release["Release Ready"] + end +``` + +[Learn more about testing frameworks](./workflows/testing.md) + +## πŸ›‘οΈ Security Workflows + +### Two-Stage Authentication + +```mermaid +sequenceDiagram + participant Job as GitHub Job + participant Base as Base Environment + participant Session as Session Environment + participant SF as Salesforce + + Job->>Base: Request Access + Base->>SF: Exchange Token + SF-->>Base: Access Token + Base->>Session: Store Token + Session-->>Job: Provide Access + Note over Session: Token Auto-Expires + Session->>Job: Revoke Access +``` + +### Protected Deployments + +```mermaid +sequenceDiagram + participant Dev as Developer + participant GH as GitHub + participant Env as Environment + participant SF as Salesforce + + Dev->>GH: Request Deploy + GH->>Env: Check Protection Rules + alt Requires Approval + Env->>GH: Request Approvals + Note over GH: Wait for Approvers + end + GH->>SF: Execute Deploy + SF-->>GH: Results +``` + +[Learn more about security workflows](./workflows/security.md) + +## πŸ“‹ Change Management + +### Standard Change Flow + +```mermaid +stateDiagram-v2 + [*] --> FeatureBranch + FeatureBranch --> Development: Create PR + Development --> Review: Tests Pass + Review --> Staging: Approved + Staging --> Production: Final Approval + Production --> [*]: Deployed +``` + +### Emergency Change Flow + +```mermaid +stateDiagram-v2 + [*] --> HotfixBranch + HotfixBranch --> Review: Critical Fix + Review --> Production: Emergency Approval + Production --> Development: Backport + Development --> [*]: Synced +``` diff --git a/docs/workflows/security.md b/docs/workflows/security.md new file mode 100644 index 0000000..72329ef --- /dev/null +++ b/docs/workflows/security.md @@ -0,0 +1,66 @@ +# πŸ›‘οΈ Security Workflows + +## Two-Stage Authentication + +Two-stage authentication is a process that separates long-term credentials from temporary access tokens to enhance security. + +### Steps + +1. **Request Access**: The GitHub job requests access from the base environment. +2. **Exchange Token**: The base environment exchanges the token with Salesforce. +3. **Store Token**: The session environment stores the token. +4. **Provide Access**: The session environment provides access to the GitHub job. +5. **Auto-Expire**: The token auto-expires after a configured time. +6. **Revoke Access**: The session environment revokes access. + +### Diagram + +```mermaid +sequenceDiagram + participant Job as GitHub Job + participant Base as Base Environment + participant Session as Session Environment + participant SF as Salesforce + + Job->>Base: Request Access + Base->>SF: Exchange Token + SF-->>Base: Access Token + Base->>Session: Store Token + Session-->>Job: Provide Access + Note over Session: Token Auto-Expires + Session->>Job: Revoke Access +``` + +## Protected Deployments + +Protected deployments ensure that deployments to production environments are secure and compliant with approval processes. + +### Steps + +1. **Request Deploy**: The developer requests a deployment. +2. **Check Protection Rules**: GitHub checks the protection rules in the environment. +3. **Request Approvals**: If required, GitHub requests approvals. +4. **Wait for Approvers**: GitHub waits for the necessary approvals. +5. **Execute Deploy**: GitHub executes the deployment to Salesforce. +6. **Deployment Results**: Salesforce returns the deployment results to GitHub. + +### Diagram + +```mermaid +sequenceDiagram + participant Dev as Developer + participant GH as GitHub + participant Env as Environment + participant SF as Salesforce + + Dev->>GH: Request Deploy + GH->>Env: Check Protection Rules + alt Requires Approval + Env->>GH: Request Approvals + Note over GH: Wait for Approvers + end + GH->>SF: Execute Deploy + SF-->>GH: Results +``` + +[Back to Workflow Overview](./index.md) diff --git a/docs/workflows/testing.md b/docs/workflows/testing.md new file mode 100644 index 0000000..7b845a6 --- /dev/null +++ b/docs/workflows/testing.md @@ -0,0 +1,79 @@ +# πŸ§ͺ Testing Frameworks + +## Unit Tests + +Unit tests are designed to test individual components or functions in isolation. They help ensure that each part of the code works as expected. + +### Apex Tests + +Apex tests are used to test the functionality of Apex classes and triggers in Salesforce. + +- **Setup**: Create test data and mock objects. +- **Execution**: Call the methods to be tested. +- **Assertions**: Verify the expected outcomes. + +### LWC Tests + +Lightning Web Component (LWC) tests are used to test the functionality of LWC components. + +- **Setup**: Create test data and mock objects. +- **Execution**: Render the component and simulate user interactions. +- **Assertions**: Verify the expected outcomes. + +## Integration Tests + +Integration tests are designed to test the interaction between different components or systems. They help ensure that the components work together as expected. + +### Org Configuration + +Integration tests for org configuration ensure that the Salesforce org is set up correctly. + +- **Setup**: Deploy the configuration to a test org. +- **Execution**: Verify that the configuration is applied correctly. +- **Assertions**: Check for any errors or inconsistencies. + +### Data Load + +Integration tests for data load ensure that data is loaded correctly into the Salesforce org. + +- **Setup**: Prepare test data files. +- **Execution**: Load the data into the test org. +- **Assertions**: Verify that the data is loaded correctly. + +### Feature Validation + +Integration tests for feature validation ensure that the features work as expected in the Salesforce org. + +- **Setup**: Deploy the feature to a test org. +- **Execution**: Test the feature functionality. +- **Assertions**: Verify the expected outcomes. + +## User Acceptance + +User acceptance tests (UAT) are designed to ensure that the system meets the user's requirements and is ready for production. + +### Sandbox Prep + +Prepare the sandbox environment for user acceptance testing. + +- **Setup**: Refresh the sandbox and deploy the latest changes. +- **Execution**: Configure the sandbox for testing. +- **Assertions**: Verify that the sandbox is ready for testing. + +### User Flows + +Test the user flows to ensure that the system meets the user's requirements. + +- **Setup**: Prepare test scenarios and test data. +- **Execution**: Execute the test scenarios. +- **Assertions**: Verify the expected outcomes. + +### Acceptance Criteria + +Verify that the system meets the acceptance criteria defined by the users. + +- **Setup**: Review the acceptance criteria. +- **Execution**: Test the system against the acceptance criteria. +- **Assertions**: Verify that the system meets the acceptance criteria. + +[Back to Workflow Overview](./index.md) diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..3f2f15c --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,29 @@ +site_name: D2X Documentation +theme: + name: material + logo: assets/images/d2x-logo.svg +extra_css: + - stylesheets/d2x.css +plugins: + - search + - mermaid2 +nav: + - Home: index.md + - Audiences: + - Overview: audiences/index.md + - Enterprise Organizations: audiences/enterprise.md + - ISV & Package Developers: audiences/isv.md + - SI Partners: audiences/partner.md + - Small Teams & Nonprofits: audiences/small.md + - Workflows: + - Overview: workflows/index.md + - Architecture: + - Overview: architecture/index.md + - GitHub Features: + - Overview: github/index.md + - Community: + - Overview: community/index.md + - Current D2X Docs: + - Overview: index.md#previous-docs + - Tutorial: tutorial.md + - Troubleshooting: reference.md \ No newline at end of file