Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/core.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: GitHub Actions Common CI

on:
push:
branches:
- master
- feature/*

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: v1

jobs:
ci:
name: Checkout main repository, release GitHub Actions Common
runs-on: ubuntu-22.04
steps:
- name: Initialize environment variables
run: |
GIT_BRANCH="${GITHUB_REF#refs/heads/}"

if [[ "master" != "${GIT_BRANCH}" ]]; then
VERSION="${VERSION}-develop"
fi

echo "GIT_BRANCH=${GIT_BRANCH}" >> ${GITHUB_ENV}
echo "VERSION=${VERSION}" >> ${GITHUB_ENV}

- name: Checkout main repository
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}

- name: Release GitHub Actions Common
run: |
./release-service.sh ${{ env.VERSION }} ${{ env.GIT_BRANCH }} ${{ env.GITHUB_SHA }} ""
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.DS_Store
.idea/
*.egg-info/
*.egg
dist/
build/
__pycache__/
3 changes: 3 additions & 0 deletions docs/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These owners will be the default owners for everything in
# the repo and will be requested for review when someone opens a pull request.
* @anovikov-el @apanasiuk-el
15 changes: 15 additions & 0 deletions examples/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# === Public GitHub package ===
# Installs from the v1 tag of a public GitHub repository
# No authentication required
git+https://github.com/edenlabllc/github_actions.common.git@v1#egg=github_actions.common

# === Private GitHub package ===
# Installs from v1 tag of a private GitHub repository
# Requires a GitHub Personal Access Token (with 'repo' scope)
# The token should be passed securely via environment variables
# Example usage:
# export GITHUB_TOKEN=ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX
# pip install -r requirements.txt
#
# Do NOT hardcode your token here!
git+https://${GITHUB_TOKEN}@github.com/edenlabllc/github_actions.common.git@v1#egg=github_actions.common
45 changes: 45 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[project]
name = "github_actions.common"
version = "v1"
description = "Common helpers and utilities for GitHub Actions used across edenlab repositories"
readme = "README.md"
license = { text = "Apache-2.0" }
requires-python = ">=3.10"
authors = [{ name = "Edenlabllc" }]
maintainers = [
{ name = "@anovikov-el" },
{ name = "@apanasiuk-el" }
]
keywords = [
"python", "github", "actions",
"ci", "cd", "devops", "infrastructure",
"aws", "azure", "gcp", "devops",
"rmk",
]
classifiers = [
"Intended Audience :: Developers",
"Topic :: Software Development :: Build Tools",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11"
]
dependencies = [
"requests~=2.32.3",
"GitPython~=3.1.44",
"PyGithub==2.5.0",
"slack_sdk~=3.34.0",
"packaging~=24.2",
"utils~=1.0.2",
"boto3~=1.37.18",
"botocore~=1.37.18"
]

[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[tool.setuptools]
package-dir = {"" = "src"}

[tool.setuptools.packages.find]
where = ["src"]
31 changes: 31 additions & 0 deletions release-service.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash

set -e

VERSION="${1}"
GIT_BRANCH="${2}"
GITHUB_SHA="${3}"
RELEASE_FILES="${4}"

echo "Release service (only for master)."
if [[ "master" == "${GIT_BRANCH}" ]]; then
echo "Configure Git user.name and user.email."
git config user.name github-actions
git config user.email github-actions@github.com

RELEASE_MSG="Release ${VERSION}"

echo "Add Git tag ${VERSION}."
git tag -a "${VERSION}" -m "${RELEASE_MSG}"
git push origin "${VERSION}" -f

if gh release view "${VERSION}" &> /dev/null; then
echo "GitHub release ${VERSION} already exists."
echo "Skipped."
else
echo "Create GitHub release ${VERSION}."
gh release create "${VERSION}" --target "${GITHUB_SHA}" --notes "${RELEASE_MSG}" ${RELEASE_FILES}
fi
else
echo "Skipped."
fi
Empty file.
48 changes: 48 additions & 0 deletions src/github_actions/common/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# github_actions/common/__init__.py

from .actions.init_project import GETTenant, ProjectInitializer, RMKConfigInitCommand
from .credentials.cluster_provider_credentials import (
AWSConfig, AzureConfig, ClusterProviders, Credentials, EnvironmentConfig, GCPConfig
)
from .input_output.input import ArgumentParser
from .input_output.output import GitHubOutput
from .notification.slack_notification import SlackNotifier
from .providers.aws_provider.aws import (
AWSSessionManager, EKSClusterFetcher, EBSVolumeFetcher, ECRManager, S3BucketManager
)
from .select_environment.allowed_environments import AllowEnvironments
from .select_environment.select_environment import (
EnvironmentSelectorInterface, EnvironmentSelector, ExtendedEnvironmentSelector
)
from .utils.cmd import BaseCommand, CMDInterface
from .utils.github_environment_variables import GitHubContext
from .utils.install_rmk import RMKInstaller


__all__ = [
"AWSConfig",
"AWSSessionManager",
"AllowEnvironments",
"ArgumentParser",
"AzureConfig",
"BaseCommand",
"CMDInterface",
"ClusterProviders",
"Credentials",
"EBSVolumeFetcher",
"ECRManager",
"EKSClusterFetcher",
"EnvironmentConfig",
"EnvironmentSelector",
"EnvironmentSelectorInterface",
"ExtendedEnvironmentSelector",
"GCPConfig",
"GETTenant",
"GitHubContext",
"GitHubOutput",
"ProjectInitializer",
"RMKConfigInitCommand",
"RMKInstaller",
"S3BucketManager",
"SlackNotifier",
]
Empty file.
78 changes: 78 additions & 0 deletions src/github_actions/common/actions/init_project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import json
import os

from argparse import Namespace
from git import Repo, GitCommandError

from ..utils.cmd import BaseCommand, CMDInterface


class RMKConfigInitCommand(BaseCommand, CMDInterface):
def __init__(self, environment: str, args: Namespace):
super().__init__(environment)
self.cluster_provider = args.rmk_cluster_provider
self.github_token = args.github_token
self.slack_notification = ""
self.slack_channel = ""
self.slack_message_details = ""
self.slack_webhook = ""

def execute(self):
self.run()

def run(self):
"""Configure Slack notifications if enabled."""
os.environ["RMK_GITHUB_TOKEN"] = self.github_token
if self.slack_notification == "true":
os.environ["RMK_SLACK_WEBHOOK"] = self.slack_webhook
os.environ["RMK_SLACK_CHANNEL"] = self.slack_channel

flags_slack_message_details = ""
if self.slack_message_details.splitlines():
flags_slack_message_details = " ".join(
[f'--slack-message-details="{detail}"' for detail in self.slack_message_details.splitlines()]
)

self.run_command(f"rmk config init --cluster-provider={self.cluster_provider}"
f" --progress-bar=false --slack-notifications {flags_slack_message_details}")
else:
self.run_command(f"rmk config init --cluster-provider={self.cluster_provider} --progress-bar=false")


class GETTenant(BaseCommand, CMDInterface):
def __init__(self, environment: str):
super().__init__(environment)

def execute(self) -> str:
return self.run()

def run(self) -> str:
output = self.run_command(f"rmk --log-format=json config view", True)
rmk_config = json.loads(output)
return rmk_config["config"]["Tenant"]


class ProjectInitializer:
GIT_CONFIG = {
"name": "github-actions",
"email": "github-actions@github.com",
}

def __init__(self, environment: str):
print("Initialize project repository.")
self.environment = environment
self.configure_git()

def configure_git(self):
"""Configure Git user settings."""
try:
repo = Repo(".")
repo.config_writer().set_value("user", "name", self.GIT_CONFIG["name"]).release()
repo.config_writer().set_value("user", "email", self.GIT_CONFIG["email"]).release()
except GitCommandError as err:
raise ValueError(f"failed to configure Git: {err}")

def configure_rmk_init(self, args: Namespace):
"""Configure Slack notifications using SlackConfigCommand."""
rmk_init = RMKConfigInitCommand(self.environment, args)
rmk_init.execute()
Empty file.
Loading