diff --git a/.github/ISSUE_TEMPLATE/new-user-request.yml b/.github/ISSUE_TEMPLATE/new-user-request.yml new file mode 100644 index 0000000..4419942 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new-user-request.yml @@ -0,0 +1,113 @@ +name: New User Request +description: Request a new Snowflake user account +title: "[User Request] " +labels: ["user-change", "infrastructure"] +body: + - type: markdown + attributes: + value: | + ## New Snowflake User Request + Please fill out this form to request a new Snowflake user account. + + - type: input + id: username + attributes: + label: Username + description: Snowflake username (typically FIRSTNAME_LASTNAME in uppercase) + placeholder: "JOHN_SMITH" + validations: + required: true + + - type: input + id: email + attributes: + label: Email Address + description: User's email address for notifications + placeholder: "john.smith@example.com" + validations: + required: true + + - type: dropdown + id: user_type + attributes: + label: User Type + description: Is this a human user or a service account? + options: + - PERSON (Human user) + - SERVICE (Service account / application) + validations: + required: true + + - type: dropdown + id: default_role + attributes: + label: Default Role + description: The default role for this user + options: + - PUBLIC (Read-only access) + - ANALYST (Query and reporting) + - DEVELOPER (Development access) + - ADMIN (Administrative access) + - CUSTOM (Specify in notes) + validations: + required: true + + - type: input + id: team + attributes: + label: Team / Department + description: Which team or department is this user part of? + placeholder: "Data Engineering" + validations: + required: true + + - type: dropdown + id: mfa_required + attributes: + label: MFA Requirement + description: Should MFA be enforced for this user? + options: + - "Yes (Recommended for human users)" + - "No (Service accounts only)" + validations: + required: true + + - type: dropdown + id: auth_method + attributes: + label: Authentication Method + description: How will this user authenticate? + options: + - RSA Key Pair (Recommended) + - Password (Emergency fallback only) + - Both (RSA primary, password backup) + validations: + required: true + + - type: textarea + id: justification + attributes: + label: Business Justification + description: Why is this user account needed? + placeholder: "This user needs access to run analytics queries for the sales team..." + validations: + required: true + + - type: textarea + id: additional_notes + attributes: + label: Additional Notes + description: Any other relevant information (specific databases, warehouses, network restrictions, etc.) + placeholder: "Needs access to ANALYTICS_DB and REPORTING warehouse..." + validations: + required: false + + - type: checkboxes + id: acknowledgment + attributes: + label: Acknowledgment + options: + - label: I understand that the user will need to complete RSA key setup after account creation + required: true + - label: I have verified this request with the appropriate manager/approver + required: true diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml new file mode 100644 index 0000000..ad34611 --- /dev/null +++ b/.github/workflows/changelog.yml @@ -0,0 +1,109 @@ +name: Generate Changelog + +on: + workflow_dispatch: + inputs: + version: + description: 'Version for changelog (e.g., v0.2.0)' + required: true + type: string + push: + tags: + - 'v*' + +jobs: + changelog: + name: Generate Changelog + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get version + id: version + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT + else + echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + fi + + - name: Get previous tag + id: prev_tag + run: | + PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") + echo "tag=$PREV_TAG" >> $GITHUB_OUTPUT + + - name: Generate changelog + id: changelog + run: | + VERSION="${{ steps.version.outputs.version }}" + PREV_TAG="${{ steps.prev_tag.outputs.tag }}" + + echo "# Changelog for $VERSION" > CHANGELOG_NEW.md + echo "" >> CHANGELOG_NEW.md + echo "Generated on $(date -u +%Y-%m-%d)" >> CHANGELOG_NEW.md + echo "" >> CHANGELOG_NEW.md + + # Determine commit range + if [ -n "$PREV_TAG" ]; then + RANGE="$PREV_TAG..HEAD" + echo "Changes since $PREV_TAG:" >> CHANGELOG_NEW.md + else + RANGE="HEAD" + echo "Initial release:" >> CHANGELOG_NEW.md + fi + echo "" >> CHANGELOG_NEW.md + + # Features + FEATURES=$(git log $RANGE --pretty=format:"- %s (%h)" --grep="^feat" 2>/dev/null || true) + if [ -n "$FEATURES" ]; then + echo "## Features" >> CHANGELOG_NEW.md + echo "$FEATURES" >> CHANGELOG_NEW.md + echo "" >> CHANGELOG_NEW.md + fi + + # Fixes + FIXES=$(git log $RANGE --pretty=format:"- %s (%h)" --grep="^fix" 2>/dev/null || true) + if [ -n "$FIXES" ]; then + echo "## Bug Fixes" >> CHANGELOG_NEW.md + echo "$FIXES" >> CHANGELOG_NEW.md + echo "" >> CHANGELOG_NEW.md + fi + + # Documentation + DOCS=$(git log $RANGE --pretty=format:"- %s (%h)" --grep="^docs" 2>/dev/null || true) + if [ -n "$DOCS" ]; then + echo "## Documentation" >> CHANGELOG_NEW.md + echo "$DOCS" >> CHANGELOG_NEW.md + echo "" >> CHANGELOG_NEW.md + fi + + # Style/Chore + OTHER=$(git log $RANGE --pretty=format:"- %s (%h)" --grep="^style\|^chore\|^refactor" 2>/dev/null || true) + if [ -n "$OTHER" ]; then + echo "## Other Changes" >> CHANGELOG_NEW.md + echo "$OTHER" >> CHANGELOG_NEW.md + echo "" >> CHANGELOG_NEW.md + fi + + # All commits (fallback if no conventional commits) + ALL=$(git log $RANGE --pretty=format:"- %s (%h)" 2>/dev/null || true) + if [ -z "$FEATURES" ] && [ -z "$FIXES" ] && [ -z "$DOCS" ] && [ -z "$OTHER" ]; then + echo "## All Changes" >> CHANGELOG_NEW.md + echo "$ALL" >> CHANGELOG_NEW.md + echo "" >> CHANGELOG_NEW.md + fi + + cat CHANGELOG_NEW.md + + - name: Upload changelog artifact + uses: actions/upload-artifact@v4 + with: + name: changelog-${{ steps.version.outputs.version }} + path: CHANGELOG_NEW.md diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..4076a61 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,121 @@ +name: Release + +on: + push: + tags: + - 'v*' + +jobs: + validate: + name: Validate Release + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install UV + uses: astral-sh/setup-uv@v4 + with: + version: "latest" + + - name: Set up Python + run: uv python install 3.12 + + - name: Install dependencies + run: uv sync --all-extras --dev + + - name: Run pre-commit + run: uv run pre-commit run --all-files + + - name: Run tests + run: uv run pytest -v --tb=short + env: + SNOWFLAKE_ACCOUNT: "test_account" + SNOWFLAKE_USER: "test_user" + SNOWFLAKE_PASSWORD: "test_password" + SNOWFLAKE_WAREHOUSE: "test_warehouse" + SNOWFLAKE_DATABASE: "test_database" + SNOWFLAKE_ROLE: "test_role" + + release: + name: Create Release + runs-on: ubuntu-latest + needs: validate + permissions: + contents: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get version from tag + id: version + run: echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + + - name: Get previous tag + id: prev_tag + run: | + PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") + echo "tag=$PREV_TAG" >> $GITHUB_OUTPUT + + - name: Generate release notes + id: notes + run: | + VERSION="${{ steps.version.outputs.version }}" + PREV_TAG="${{ steps.prev_tag.outputs.tag }}" + + { + echo "notes</dev/null || true) + if [ -n "$FEATURES" ]; then + echo "### Features" + echo "$FEATURES" + echo "" + fi + + # Fixes + FIXES=$(git log $RANGE --pretty=format:"- %s" --grep="^fix" 2>/dev/null || true) + if [ -n "$FIXES" ]; then + echo "### Bug Fixes" + echo "$FIXES" + echo "" + fi + + # Other + OTHER=$(git log $RANGE --pretty=format:"- %s" --grep="^docs\|^style\|^chore\|^refactor" 2>/dev/null || true) + if [ -n "$OTHER" ]; then + echo "### Other" + echo "$OTHER" + echo "" + fi + + if [ -n "$PREV_TAG" ]; then + echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/$PREV_TAG...$VERSION" + fi + + echo "EOF" + } >> $GITHUB_OUTPUT + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.version.outputs.version }} + name: ${{ steps.version.outputs.version }} + body: ${{ steps.notes.outputs.notes }} + draft: false + prerelease: ${{ contains(steps.version.outputs.version, '-') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/snowddl/PROJ_STRIPE/PROJ_STRIPE/params.yaml b/snowddl/PROJ_STRIPE/PROJ_STRIPE/params.yaml deleted file mode 100644 index f1297ea..0000000 --- a/snowddl/PROJ_STRIPE/PROJ_STRIPE/params.yaml +++ /dev/null @@ -1,3 +0,0 @@ -comment: "dbt-managed Stripe transformation schema - Contains models from dbt_stripe project" -retention_time: 7 # 7 days retention for transformed data -is_transient: false diff --git a/snowddl/PROJ_STRIPE/params.yaml b/snowddl/PROJ_STRIPE/params.yaml deleted file mode 100644 index 2975ca8..0000000 --- a/snowddl/PROJ_STRIPE/params.yaml +++ /dev/null @@ -1,2 +0,0 @@ -comment: Project database for processed Stripe analytics and reporting - Full sandbox for dbt transformations managed by DBT_ANALYTICS_ROLE -is_sandbox: true diff --git a/snowddl/SNOWTOWER_APPS/PUBLIC/params.yaml b/snowddl/SNOWTOWER_APPS/PUBLIC/params.yaml deleted file mode 100644 index 1990d76..0000000 --- a/snowddl/SNOWTOWER_APPS/PUBLIC/params.yaml +++ /dev/null @@ -1,3 +0,0 @@ -comment: "SnowTower Streamlit apps schema - Contains app configuration and metadata" -retention_time: 7 -is_transient: false diff --git a/snowddl/SNOWTOWER_APPS/params.yaml b/snowddl/SNOWTOWER_APPS/params.yaml deleted file mode 100644 index 7c5d41f..0000000 --- a/snowddl/SNOWTOWER_APPS/params.yaml +++ /dev/null @@ -1,2 +0,0 @@ -comment: Database for Streamlit applications and SnowTower infrastructure deployment -is_sandbox: false diff --git a/snowddl/SOURCE_STRIPE/STRIPE_WHY/params.yaml b/snowddl/SOURCE_STRIPE/STRIPE_WHY/params.yaml deleted file mode 100644 index 2d78abd..0000000 --- a/snowddl/SOURCE_STRIPE/STRIPE_WHY/params.yaml +++ /dev/null @@ -1,2 +0,0 @@ -comment: DLT-managed Stripe data schema - Contains raw Stripe webhook and API data -retention_time: 1 # 1 day retention for raw source data diff --git a/snowddl/SOURCE_STRIPE/params.yaml b/snowddl/SOURCE_STRIPE/params.yaml deleted file mode 100644 index 2060748..0000000 --- a/snowddl/SOURCE_STRIPE/params.yaml +++ /dev/null @@ -1,2 +0,0 @@ -comment: Source database for raw Stripe data ingestion -is_sandbox: true