Merge pull request #77 from dawnsystem/claude/fix-github-tests-019ptUhQs4TYnT2CyQNLV6bF

Claude/fix GitHub tests 019pt uh qs4 t yn t2 cy qnlv6b f
This commit is contained in:
dawnsystem 2025-11-18 00:15:20 +01:00 committed by GitHub
commit d1dcb7c678
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 188 additions and 45 deletions

View file

@ -74,6 +74,100 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }} python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
- name: Check files - name: Check files
uses: pre-commit/action@v3.0.1 uses: pre-commit/action@v3.0.1
verify-environment:
name: "Verify Environment & Services"
runs-on: ubuntu-24.04
needs:
- pre-commit
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Verify Docker installation
run: |
if ! command -v docker &> /dev/null; then
echo "✗ Docker is not installed"
exit 1
fi
echo "✓ Docker is installed: $(docker --version)"
- name: Verify docker-compose installation
run: |
if ! command -v docker &> /dev/null || ! docker compose version &> /dev/null; then
echo "✗ docker-compose is not installed"
exit 1
fi
echo "✓ docker compose is installed: $(docker compose version)"
- name: Verify compose file exists
env:
COMPOSE_FILE: docker/compose/docker-compose.intellidocs.yml
run: |
if [ ! -f "$COMPOSE_FILE" ]; then
echo "✗ Compose file not found: $COMPOSE_FILE"
exit 1
fi
echo "✓ Compose file found: $COMPOSE_FILE"
- name: Set up Python
id: setup-python
uses: actions/setup-python@v6
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v6
with:
version: ${{ env.DEFAULT_UV_VERSION }}
enable-cache: true
python-version: ${{ steps.setup-python.outputs.python-version }}
- name: Generate and verify requirements.txt
run: |
uv export --quiet --no-dev --all-extras --format requirements-txt --output-file requirements.txt
if [ ! -f "requirements.txt" ]; then
echo "✗ requirements.txt was not generated"
exit 1
fi
echo "✓ requirements.txt generated successfully"
- name: Verify Python dependencies installation
run: |
# Verify that requirements.txt can be parsed
if ! python -c "
import sys
try:
with open('requirements.txt', 'r') as f:
lines = f.readlines()
print(f'✓ requirements.txt has {len(lines)} entries')
sys.exit(0)
except Exception as e:
print(f'✗ Error reading requirements.txt: {e}')
sys.exit(1)
"; then
exit 1
fi
- name: Start Redis service
run: |
docker compose --file docker/compose/docker-compose.intellidocs.yml up -d broker
echo "Waiting for Redis to be ready..."
sleep 10
- name: Verify Redis is responding
run: |
MAX_RETRIES=30
RETRY_COUNT=0
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
if docker compose --file docker/compose/docker-compose.intellidocs.yml exec -T broker redis-cli ping &> /dev/null; then
echo "✓ Redis is responding"
exit 0
fi
RETRY_COUNT=$((RETRY_COUNT + 1))
echo "Waiting for Redis... (attempt $RETRY_COUNT/$MAX_RETRIES)"
sleep 2
done
echo "✗ Redis is not responding after $MAX_RETRIES attempts"
docker compose --file docker/compose/docker-compose.intellidocs.yml logs broker
exit 1
- name: Stop services
if: always()
run: |
docker compose --file docker/compose/docker-compose.intellidocs.yml down -v
documentation: documentation:
name: "Build & Deploy Documentation" name: "Build & Deploy Documentation"
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04

View file

@ -25,10 +25,10 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v5 uses: actions/setup-python@v6
with: with:
python-version: '3.12' python-version: '3.12'
@ -104,7 +104,7 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
@ -242,7 +242,7 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Create Release - name: Create Release
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2

View file

@ -83,11 +83,18 @@ jobs:
const pr = context.payload.pull_request; const pr = context.payload.pull_request;
const user = pr.user.login; const user = pr.user.login;
// Try to get org members, but handle if this is not an org
let memberLogins = [];
try {
const { data: members } = await github.rest.orgs.listMembers({ const { data: members } = await github.rest.orgs.listMembers({
org: 'paperless-ngx', org: context.repo.owner,
}); });
memberLogins = members.map(m => m.login.toLowerCase());
} catch (error) {
// If not an organization, only skip for repo collaborators
core.info('Not an organization or unable to fetch members');
}
const memberLogins = members.map(m => m.login.toLowerCase());
if (memberLogins.includes(user.toLowerCase())) { if (memberLogins.includes(user.toLowerCase())) {
core.info('Skipping comment: user is org member'); core.info('Skipping comment: user is org member');
return; return;
@ -98,7 +105,7 @@ jobs:
"Thank you very much for submitting this PR to us!\n\n" + "Thank you very much for submitting this PR to us!\n\n" +
"This is what will happen next:\n\n" + "This is what will happen next:\n\n" +
"1. CI tests will run against your PR to ensure quality and consistency.\n" + "1. CI tests will run against your PR to ensure quality and consistency.\n" +
"2. Next, human contributors from paperless-ngx review your changes.\n" + "2. Next, human contributors will review your changes.\n" +
"3. Please address any issues that come up during the review as soon as you are able to.\n" + "3. Please address any issues that come up during the review as soon as you are able to.\n" +
"4. If accepted, your pull request will be merged into the `dev` branch and changes there will be tested further.\n" + "4. If accepted, your pull request will be merged into the `dev` branch and changes there will be tested further.\n" +
"5. Eventually, changes from you and other contributors will be merged into `main` and a new release will be made.\n\n" + "5. Eventually, changes from you and other contributors will be merged into `main` and a new release will be made.\n\n" +

View file

@ -63,6 +63,7 @@ jobs:
- name: Commit changes - name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v6 uses: stefanzweifel/git-auto-commit-action@v6
with: with:
token: ${{ secrets.GITHUB_TOKEN }}
file_pattern: 'src-ui/messages.xlf src/locale/en_US/LC_MESSAGES/django.po' file_pattern: 'src-ui/messages.xlf src/locale/en_US/LC_MESSAGES/django.po'
commit_message: "Auto translate strings" commit_message: "Auto translate strings"
commit_user_name: "GitHub Actions" commit_user_name: "GitHub Actions"

View file

@ -18,8 +18,8 @@ import {
} from '@angular/core' } from '@angular/core'
import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap' import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap'
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons' import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
import { Subject } from 'rxjs' import { Subject, of } from 'rxjs'
import { takeUntil } from 'rxjs/operators' import { takeUntil, catchError } from 'rxjs/operators'
import { import {
AISuggestion, AISuggestion,
AISuggestionStatus, AISuggestionStatus,
@ -134,7 +134,16 @@ export class AiSuggestionsPanelComponent implements OnChanges, OnDestroy {
(s) => s.type === AISuggestionType.Tag (s) => s.type === AISuggestionType.Tag
) )
if (tagSuggestions.length > 0) { if (tagSuggestions.length > 0) {
this.tagService.listAll().pipe(takeUntil(this.destroy$)).subscribe((tags) => { this.tagService
.listAll()
.pipe(
takeUntil(this.destroy$),
catchError((error) => {
console.error('Failed to load tags:', error)
return of({ results: [] })
})
)
.subscribe((tags) => {
this.tags = tags.results this.tags = tags.results
this.updateSuggestionLabels() this.updateSuggestionLabels()
}) })
@ -145,7 +154,16 @@ export class AiSuggestionsPanelComponent implements OnChanges, OnDestroy {
(s) => s.type === AISuggestionType.Correspondent (s) => s.type === AISuggestionType.Correspondent
) )
if (correspondentSuggestions.length > 0) { if (correspondentSuggestions.length > 0) {
this.correspondentService.listAll().pipe(takeUntil(this.destroy$)).subscribe((correspondents) => { this.correspondentService
.listAll()
.pipe(
takeUntil(this.destroy$),
catchError((error) => {
console.error('Failed to load correspondents:', error)
return of({ results: [] })
})
)
.subscribe((correspondents) => {
this.correspondents = correspondents.results this.correspondents = correspondents.results
this.updateSuggestionLabels() this.updateSuggestionLabels()
}) })
@ -156,7 +174,16 @@ export class AiSuggestionsPanelComponent implements OnChanges, OnDestroy {
(s) => s.type === AISuggestionType.DocumentType (s) => s.type === AISuggestionType.DocumentType
) )
if (documentTypeSuggestions.length > 0) { if (documentTypeSuggestions.length > 0) {
this.documentTypeService.listAll().pipe(takeUntil(this.destroy$)).subscribe((documentTypes) => { this.documentTypeService
.listAll()
.pipe(
takeUntil(this.destroy$),
catchError((error) => {
console.error('Failed to load document types:', error)
return of({ results: [] })
})
)
.subscribe((documentTypes) => {
this.documentTypes = documentTypes.results this.documentTypes = documentTypes.results
this.updateSuggestionLabels() this.updateSuggestionLabels()
}) })
@ -167,7 +194,16 @@ export class AiSuggestionsPanelComponent implements OnChanges, OnDestroy {
(s) => s.type === AISuggestionType.StoragePath (s) => s.type === AISuggestionType.StoragePath
) )
if (storagePathSuggestions.length > 0) { if (storagePathSuggestions.length > 0) {
this.storagePathService.listAll().pipe(takeUntil(this.destroy$)).subscribe((storagePaths) => { this.storagePathService
.listAll()
.pipe(
takeUntil(this.destroy$),
catchError((error) => {
console.error('Failed to load storage paths:', error)
return of({ results: [] })
})
)
.subscribe((storagePaths) => {
this.storagePaths = storagePaths.results this.storagePaths = storagePaths.results
this.updateSuggestionLabels() this.updateSuggestionLabels()
}) })
@ -178,7 +214,16 @@ export class AiSuggestionsPanelComponent implements OnChanges, OnDestroy {
(s) => s.type === AISuggestionType.CustomField (s) => s.type === AISuggestionType.CustomField
) )
if (customFieldSuggestions.length > 0) { if (customFieldSuggestions.length > 0) {
this.customFieldsService.listAll().pipe(takeUntil(this.destroy$)).subscribe((customFields) => { this.customFieldsService
.listAll()
.pipe(
takeUntil(this.destroy$),
catchError((error) => {
console.error('Failed to load custom fields:', error)
return of({ results: [] })
})
)
.subscribe((customFields) => {
this.customFields = customFields.results this.customFields = customFields.results
this.updateSuggestionLabels() this.updateSuggestionLabels()
}) })

View file

@ -1,6 +1,6 @@
import { HttpClient } from '@angular/common/http' import { HttpClient } from '@angular/common/http'
import { Injectable, inject } from '@angular/core' import { Injectable, inject } from '@angular/core'
import { BehaviorSubject, Observable, interval, Subscription } from 'rxjs' import { BehaviorSubject, Observable, interval, Subscription, of } from 'rxjs'
import { catchError, map, startWith, switchMap } from 'rxjs/operators' import { catchError, map, startWith, switchMap } from 'rxjs/operators'
import { AIStatus } from 'src/app/data/ai-status' import { AIStatus } from 'src/app/data/ai-status'
import { environment } from 'src/environments/environment' import { environment } from 'src/environments/environment'
@ -86,19 +86,15 @@ export class AIStatusService {
}), }),
catchError((error) => { catchError((error) => {
this.loading = false this.loading = false
console.warn('Failed to fetch AI status, using mock data:', error) console.warn('Failed to fetch AI status:', error)
// Return mock data if endpoint doesn't exist yet // Return default status if endpoint fails
return [ return of({
{ active: false,
active: true,
processing: false, processing: false,
documents_scanned_today: 42, documents_scanned_today: 0,
suggestions_applied: 15, suggestions_applied: 0,
pending_deletion_requests: 2, pending_deletion_requests: 0,
last_scan: new Date().toISOString(), })
version: '1.0.0',
},
]
}) })
) )
} }