Skip to content

Commit

Permalink
Merge pull request #32 from muselab-d2x/jlantz/update-auth-structure
Browse files Browse the repository at this point in the history
Update authentication structure and decouple from GitHub Environments
  • Loading branch information
jlantz authored Oct 31, 2024
2 parents 9a9438d + 8462b62 commit c255f44
Show file tree
Hide file tree
Showing 38 changed files with 1,796 additions and 477 deletions.
Binary file added .coverage
Binary file not shown.
2 changes: 1 addition & 1 deletion .github/actions/collect-org-info/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ runs:
fi
shell: bash
env:
GITHUB_TOKEN: ${{ github.token }}
GITHUB_TOKEN: ${{ github.token }}
47 changes: 47 additions & 0 deletions .github/workflows/delete-org-session.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Delete Org Session

on:
workflow_call:
inputs:
environment_name:
description: "The name of the GitHub Environment to delete the org session from"
required: true
type: string
github_auth_environment:
description: "The name of the GitHub Environment to get the GitHub Access token from"
required: true
type: string
secrets:
github-token:
required: true

jobs:
delete-org-session:
name: "Delete Org Session"
runs-on: ubuntu-latest
steps:
- name: Get GitHub Access Token
run: |
echo "Retrieving GitHub Access Token from environment: ${{ inputs.github_auth_environment }}"
GITHUB_ACCESS_TOKEN=$(gh api \
-H "Authorization: token ${{ secrets.github-token }}" \
"/repos/${{ github.repository }}/environments/${{ inputs.github_auth_environment }}/variables/GITHUB_ACCESS_TOKEN" \
| jq -r '.value')
echo "GITHUB_ACCESS_TOKEN=${GITHUB_ACCESS_TOKEN}" >> $GITHUB_ENV
shell: bash

- name: Delete Org Session
run: |
echo "Deleting org session from environment: ${{ inputs.environment_name }}"
gh api \
-X DELETE \
-H "Authorization: token ${{ env.GITHUB_ACCESS_TOKEN }}" \
"/repos/${{ github.repository }}/environments/${{ inputs.environment_name }}/variables/ACCESS_TOKEN"
shell: bash

- name: Add Job Summary
run: |
echo "## Org Session Deletion Summary" >> $GITHUB_STEP_SUMMARY
echo "Environment: ${{ inputs.environment_name }}" >> $GITHUB_STEP_SUMMARY
echo "Status: Org session deleted successfully" >> $GITHUB_STEP_SUMMARY
shell: bash
16 changes: 10 additions & 6 deletions .github/workflows/org-login-slack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,20 @@ jobs:
d2x-login-url:
name: Use d2x to generate a login url
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
environment: ${{ github.event.inputs.environment }}
steps:
- run: pip install d2x
- run: pip install git+https://github.com/muselab-d2x/d2x.git@jlantz/update-auth-structure

- name: Generate Login URL for ${{ github.event.inputs.environment }}
- id: generate_login_url
name: Generate Login URL for ${{ github.event.inputs.environment }}
env:
AUTH_URL: ${{ secrets.sfdx-auth-url }}
run: python -m d2x.auth.sf.login_url > login_url.txt
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: |
Expand All @@ -40,6 +44,6 @@ jobs:
-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.read_url.outputs.login_url }}"
"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
35 changes: 35 additions & 0 deletions .github/workflows/test-github-auth.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Test GitHub Auth

on:
push:
branches:
- "**"

jobs:
test-github-auth:
runs-on: ubuntu-latest
environment: test
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 }}"
CUMULUSCI_SERVICE_github: '{ "username": "${{ github.actor }}", "token": "${{ secrets.github-token }}", "email": "${{ secrets.gh-email }}" }'
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Auth to DevHub
run: /usr/local/bin/devhub.sh
- name: Test GitHub Auth
run: |
d2x auth url
d2x auth login
shell: bash
- name: Record API Requests
run: |
pip install vcrpy
vcrpy --record-mode=once --filter-headers Authorization --filter-headers X-Auth-Token --filter-headers X-API-Key
shell: bash
54 changes: 54 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Run Tests
on:
push:
branches:
- "**"
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"

- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 1.7.1
virtualenvs-create: true
virtualenvs-in-project: true

- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
.venv
~/.cache/pypoetry
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
restore-keys: |
${{ runner.os }}-poetry-
- name: Install dependencies
run: |
poetry install --with dev
- name: Run tests
run: |
poetry run pytest tests/ --cov=d2x --cov-report=xml --junitxml=tests/results.xml
echo "✅ Tests and coverage completed"
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage.xml

- name: Upload test results
uses: actions/upload-artifact@v4
with:
name: test-results
path: tests/results.xml
25 changes: 25 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Debug Active File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": false
},
{
"name": "Python: Debug Tests",
"type": "python",
"request": "launch",
"module": "pytest",
"args": [
"tests"
],
"console": "integratedTerminal",
"justMyCode": false
}
]
}
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"python.testing.pytestArgs": [
"tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
}
1 change: 1 addition & 0 deletions d2x/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# d2x.api module
91 changes: 91 additions & 0 deletions d2x/api/gh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import os
import requests

GITHUB_REPO = os.environ.get("GITHUB_REPOSITORY")


def get_github_token() -> str:
"""Get the GitHub token from the environment"""
token = os.environ.get("GITHUB_TOKEN")
if not token:
raise ValueError("GITHUB_TOKEN environment variable not set")
return token


def get_repo_full_name() -> str:
"""Get the full name of the GitHub repository"""
repo = os.environ.get("GITHUB_REPOSITORY")
if not repo:
raise ValueError("GITHUB_REPOSITORY environment variable not set")
return repo


def set_environment_variable(env_name: str, var_name: str, var_value: str) -> None:
"""Set a variable in a GitHub Environment"""
token = os.environ.get("GITHUB_TOKEN")
repo = os.environ.get("GITHUB_REPOSITORY")
if not token:
raise ValueError("GITHUB_TOKEN environment variable not set")

url = f"https://api.github.com/repos/{GITHUB_REPO}/environments/{env_name}/variables/{var_name}"
headers = {
"Authorization": f"Bearer {token}",
"Accept": "application/vnd.github.v3+json",
}
data = {"name": var_name, "value": var_value}

response = requests.put(url, headers=headers, json=data)
response.raise_for_status()


def get_environment_variable(env_name: str, var_name: str) -> str:
"""Get a variable from a GitHub Environment"""
token = os.environ.get("GITHUB_TOKEN")
if not token:
raise ValueError("GITHUB_TOKEN environment variable not set")

url = f"https://api.github.com/repos/{GITHUB_REPO}/environments/{env_name}/variables/{var_name}"
headers = {
"Authorization": f"Bearer {token}",
"Accept": "application/vnd.github.v3+json",
}

response = requests.get(url, headers=headers)
response.raise_for_status()

return response.json()["value"]


def set_environment_secret(env_name: str, secret_name: str, secret_value: str) -> None:
"""Set a secret in a GitHub Environment"""
token = os.environ.get("GITHUB_TOKEN")
if not token:
raise ValueError("GITHUB_TOKEN environment variable not set")

url = f"https://api.github.com/repos/{GITHUB_REPO}/environments/{env_name}/secrets/{secret_name}"
headers = {
"Authorization": f"Bearer {token}",
"Accept": "application/vnd.github.v3+json",
}
data = {"encrypted_value": secret_value}

response = requests.put(url, headers=headers, json=data)
response.raise_for_status()


def get_environment_secret(env_name: str, secret_name: str) -> str:
"""Get a secret from a GitHub Environment"""
token = os.environ.get("GITHUB_TOKEN")
if not token:
raise ValueError("GITHUB_TOKEN environment variable not set")

url = f"https://api.github.com/repos/{GITHUB_REPO}/environments/{env_name}/secrets/{secret_name}"
headers = {
"Authorization": f"Bearer {token}",
"Accept": "application/vnd.github.v3+json",
}

response = requests.get(url, headers=headers)
response.raise_for_status()

return response.json()["encrypted_value"]
1 change: 1 addition & 0 deletions d2x/auth/sf/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This is the __init__.py file for the d2x.auth.sf module.
Loading

0 comments on commit c255f44

Please sign in to comment.