From 1b9f2e53b4b1f78c8ca52cb6d41eef68c9d312d2 Mon Sep 17 00:00:00 2001 From: rae sharp <8883519+tr0njavolta@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:06:05 -0500 Subject: [PATCH 1/3] Create main.yml Signed-off-by: raesharp <8883519+tr0njavolta@users.noreply.github.com> --- .github/workflows/main.yml | 102 +++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..10f260b64 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,102 @@ +name: Documentation Freshness Check +on: + schedule: + - cron: '0 0 1 * *' # Run monthly on the 1st at midnight + workflow_dispatch: # Allow manual trigger + +jobs: + check_freshness: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Need full history for git log + + - uses: actions/setup-python@v4 + with: + python-version: '3.x' + + - name: Create scripts directory + run: mkdir -p .github/scripts + + - name: Copy Python script + run: | + cat > .github/scripts/check_freshness.py << 'EOL' + import os + import subprocess + from datetime import datetime, timedelta + + FRESHNESS_PERIOD = timedelta(days=180) # 6 months + IGNORED_FILES = ["_index.md"] # Add any files to ignore + now = datetime.now() + + def get_last_modified_time(file_path): + result = subprocess.run( + ['git', 'log', '-1', '--format=%ct', file_path], + stdout=subprocess.PIPE, + text=True + ) + if not result.stdout.strip(): + return now # Return current time for new files + timestamp = int(result.stdout.strip()) + return datetime.fromtimestamp(timestamp) + + def check_freshness(directory): + stale_files = [] + for root, _, files in os.walk(directory): + for file in files: + if file.endswith(".md"): + relative_path = os.path.relpath(os.path.join(root, file), start=directory) + if file in IGNORED_FILES: + continue + last_modified = get_last_modified_time(os.path.join(root, file)) + time_diff = now - last_modified + if time_diff > FRESHNESS_PERIOD: + stale_files.append((relative_path, last_modified)) + return stale_files + + docs_directory = "docs/content/master" # Crossplane docs directory + stale_docs = check_freshness(docs_directory) + sorted_stale_docs = sorted(stale_docs, key=lambda x: x[1]) + + if sorted_stale_docs: + issue_body = "## Stale Documentation Alert\n\n" + issue_body += "The following documentation files have not been modified in the last 6 months:\n\n" + for doc, mod_time in sorted_stale_docs: + issue_body += f"- `{doc}` (Last Modified: {mod_time.strftime('%Y-%m-%d')})\n" + issue_body += "\nPlease review these documents to ensure they are up-to-date and accurate." + + with open("issue_body.txt", "w") as f: + f.write(issue_body) + + with open("has_stale.txt", "w") as f: + f.write("true") + else: + with open("has_stale.txt", "w") as f: + f.write("false") + EOL + + - name: Run freshness check + run: python3 .github/scripts/check_freshness.py + + - name: Check for stale docs + id: check + run: | + HAS_STALE=$(cat has_stale.txt) + echo "has_stale=$HAS_STALE" >> $GITHUB_OUTPUT + + - name: Create Issue + if: steps.check.outputs.has_stale == 'true' + uses: actions/github-script@v6 + with: + script: | + const fs = require('fs'); + const issueBody = fs.readFileSync('issue_body.txt', 'utf8'); + + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: '📚 Documentation Freshness Check Results', + body: issueBody, + labels: ['documentation', 'maintenance'] + }); From aa02d0775a9175ecf42ea2e7add72f098ebc56a4 Mon Sep 17 00:00:00 2001 From: rae sharp <8883519+tr0njavolta@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:26:34 -0500 Subject: [PATCH 2/3] Update main.yml Signed-off-by: raesharp <8883519+tr0njavolta@users.noreply.github.com> --- .github/workflows/main.yml | 93 ++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 40 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 10f260b64..69e904c82 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,6 +4,10 @@ on: - cron: '0 0 1 * *' # Run monthly on the 1st at midnight workflow_dispatch: # Allow manual trigger +permissions: + issues: write + contents: read + jobs: check_freshness: runs-on: ubuntu-latest @@ -15,19 +19,29 @@ jobs: - uses: actions/setup-python@v4 with: python-version: '3.x' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install requests - - name: Create scripts directory - run: mkdir -p .github/scripts - - - name: Copy Python script + - name: Create and run freshness check script + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - cat > .github/scripts/check_freshness.py << 'EOL' + cat > check_freshness.py << 'EOL' import os import subprocess + import requests from datetime import datetime, timedelta - FRESHNESS_PERIOD = timedelta(days=180) # 6 months - IGNORED_FILES = ["_index.md"] # Add any files to ignore + # Configuration + FRESHNESS_PERIOD = timedelta(days=180) # 180 days (6 months) + IGNORED_FILES = ["_index.md"] + GITHUB_TOKEN = os.environ.get('GITHUB_TOKEN') + GITHUB_REPO = os.environ.get('GITHUB_REPOSITORY', 'owner/repo') + GITHUB_API_URL = f"https://api.github.com/repos/{GITHUB_REPO}/issues" + now = datetime.now() def get_last_modified_time(file_path): @@ -55,7 +69,33 @@ jobs: stale_files.append((relative_path, last_modified)) return stale_files - docs_directory = "docs/content/master" # Crossplane docs directory + def create_github_issue(body): + if not GITHUB_TOKEN: + print("Error: GITHUB_TOKEN environment variable not set") + return False + + headers = { + 'Authorization': f'token {GITHUB_TOKEN}', + 'Accept': 'application/vnd.github.v3+json' + } + + issue_data = { + 'title': '📚 Documentation Freshness Check Results', + 'body': body, + 'labels': ['documentation', 'maintenance'] + } + + response = requests.post(GITHUB_API_URL, headers=headers, json=issue_data) + if response.status_code == 201: + print(f"Issue created successfully: {response.json()['html_url']}") + return True + else: + print(f"Failed to create issue. Status code: {response.status_code}") + print(f"Response: {response.text}") + return False + + # Main execution + docs_directory = "content" stale_docs = check_freshness(docs_directory) sorted_stale_docs = sorted(stale_docs, key=lambda x: x[1]) @@ -66,37 +106,10 @@ jobs: issue_body += f"- `{doc}` (Last Modified: {mod_time.strftime('%Y-%m-%d')})\n" issue_body += "\nPlease review these documents to ensure they are up-to-date and accurate." - with open("issue_body.txt", "w") as f: - f.write(issue_body) - - with open("has_stale.txt", "w") as f: - f.write("true") + print(issue_body) # Print to console + create_github_issue(issue_body) # Create GitHub issue else: - with open("has_stale.txt", "w") as f: - f.write("false") + print("All documentation is up to date!") EOL - - - name: Run freshness check - run: python3 .github/scripts/check_freshness.py - - - name: Check for stale docs - id: check - run: | - HAS_STALE=$(cat has_stale.txt) - echo "has_stale=$HAS_STALE" >> $GITHUB_OUTPUT - - - name: Create Issue - if: steps.check.outputs.has_stale == 'true' - uses: actions/github-script@v6 - with: - script: | - const fs = require('fs'); - const issueBody = fs.readFileSync('issue_body.txt', 'utf8'); - - await github.rest.issues.create({ - owner: context.repo.owner, - repo: context.repo.repo, - title: '📚 Documentation Freshness Check Results', - body: issueBody, - labels: ['documentation', 'maintenance'] - }); + + python check_freshness.py From 76b29478e996191f6b85bec2b1dc036bd71fd1a5 Mon Sep 17 00:00:00 2001 From: rae sharp <8883519+tr0njavolta@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:27:46 -0500 Subject: [PATCH 3/3] Rename main.yml to check_freshness.yml Signed-off-by: raesharp <8883519+tr0njavolta@users.noreply.github.com> --- .github/workflows/{main.yml => check_freshness.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{main.yml => check_freshness.yml} (100%) diff --git a/.github/workflows/main.yml b/.github/workflows/check_freshness.yml similarity index 100% rename from .github/workflows/main.yml rename to .github/workflows/check_freshness.yml