diff --git a/.github/workflows/test-artifact-limit.yml b/.github/workflows/test-artifact-limit.yml new file mode 100644 index 0000000..0aaced9 --- /dev/null +++ b/.github/workflows/test-artifact-limit.yml @@ -0,0 +1,198 @@ +name: Test Artifact Upload Limit + +on: + workflow_dispatch: + +jobs: + test-artifact-limit: + runs-on: ubuntu-latest + permissions: + contents: read + actions: write + + steps: + - name: Create 501 test files + run: | + echo "Creating 501 test files..." + mkdir -p test-files + for i in {1..501}; do + echo "This is test file number $i" > test-files/file-$(printf "%03d" $i).txt + done + echo "Created $(ls test-files | wc -l) files" + + - name: Setup Node.js for artifact uploads + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Create upload script + run: | + cat > upload-artifacts.js << 'EOF' + const { DefaultArtifactClient } = require('@actions/artifact'); + const fs = require('fs'); + const path = require('path'); + + async function uploadIndividualArtifacts() { + const artifact = new DefaultArtifactClient(); + const testFilesDir = 'test-files'; + const files = fs.readdirSync(testFilesDir).sort(); + + console.log(`Found ${files.length} files to upload as individual artifacts`); + console.log('Attempting to upload 501 individual artifacts...\n'); + + let successCount = 0; + let failCount = 0; + + for (let i = 0; i < files.length; i++) { + const file = files[i]; + const artifactName = `test-artifact-${String(i + 1).padStart(3, '0')}`; + const filePath = path.join(testFilesDir, file); + + try { + console.log(`[${i + 1}/${files.length}] Uploading ${artifactName}...`); + + // Upload artifact using the DefaultArtifactClient API + const uploadResponse = await artifact.uploadArtifact( + artifactName, + [filePath], + testFilesDir + ); + + successCount++; + if ((i + 1) % 50 === 0) { + console.log(` Progress: ${successCount} artifacts uploaded successfully`); + } + } catch (error) { + failCount++; + console.error(` ✗ Failed to upload ${artifactName}`); + console.error(` Error: ${error.message}`); + + // Report when we hit the artifact limit and exit + console.error(`\n❌ ARTIFACT LIMIT ERROR at artifact ${i + 1}`); + console.error(`Successfully uploaded: ${successCount} artifacts`); + console.error(`Failed uploads: ${failCount} artifacts`); + console.error(`Expected limit: 500 artifacts per workflow run`); + throw error; + } + } + + console.log(`\n✅ Upload complete: ${successCount} successful, ${failCount} failed`); + } + + uploadIndividualArtifacts().catch(error => { + console.error('\nUpload process terminated due to error'); + process.exit(1); + }); + EOF + + - name: Install @actions/artifact package + run: | + npm install @actions/artifact@2.1.10 + + - name: Attempt to upload 501 files as separate artifacts + id: upload-individual-artifacts + continue-on-error: true + run: | + echo "Starting upload of 501 individual artifacts..." + echo "This will test the 500 artifact limit per workflow run." + echo "" + node upload-artifacts.js + + - name: Report individual upload results + if: always() + run: | + echo "" + echo "=========================================" + if [ "${{ steps.upload-individual-artifacts.outcome }}" == "failure" ]; then + echo "✗ Individual artifact upload failed (as expected!)" + echo "The workflow hit the 500 artifact limit." + elif [ "${{ steps.upload-individual-artifacts.outcome }}" == "success" ]; then + echo "⚠️ Individual artifact upload completed." + echo "Note: This might mean all 501 were uploaded (limit may have changed)" + echo "or uploads were throttled/limited by another mechanism." + fi + echo "=========================================" + echo "" + + - name: Create a single zip file containing all 501 files + run: | + echo "Creating a single zip archive containing all 501 files..." + cd test-files + zip -q -r ../all-files.zip . + cd .. + echo "" + echo "✓ Zip file created: all-files.zip" + ls -lh all-files.zip + echo "" + echo "Number of files in zip:" + unzip -l all-files.zip | tail -1 + + - name: Upload single zip file as artifact + uses: actions/upload-artifact@v4 + with: + name: all-501-files-zipped + path: all-files.zip + + - name: Verify zip artifact upload + run: | + echo "" + echo "✓ Successfully uploaded zip file containing all 501 files as a single artifact!" + echo "This demonstrates the recommended workaround for the 500 artifact limit." + + - name: Generate workflow summary + if: always() + run: | + echo "# Artifact Upload Limit Test Results" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "This workflow tests GitHub Actions' **500 artifact limit** per workflow run." >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "---" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + echo "## Test Setup" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- 📁 **Files created:** 501 test files" >> $GITHUB_STEP_SUMMARY + echo "- 🚫 **Artifact limit:** 500 artifacts per workflow run" >> $GITHUB_STEP_SUMMARY + echo "- 📦 **Upload method:** @actions/artifact package" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + echo "## Test 1: Upload 501 Individual Artifacts" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + if [ "${{ steps.upload-individual-artifacts.outcome }}" == "failure" ]; then + echo "**Result:** ❌ Failed (as expected)" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- The upload failed when attempting to exceed 500 artifacts" >> $GITHUB_STEP_SUMMARY + echo "- First 500 artifacts uploaded successfully" >> $GITHUB_STEP_SUMMARY + echo "- Artifact 501 triggered the limit error" >> $GITHUB_STEP_SUMMARY + echo "- Error message: *'Unable to upload artifact. Maximum number of artifacts (500) has been reached.'*" >> $GITHUB_STEP_SUMMARY + elif [ "${{ steps.upload-individual-artifacts.outcome }}" == "success" ]; then + echo "**Result:** ⚠️ Completed" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- All 501 artifacts may have been uploaded" >> $GITHUB_STEP_SUMMARY + echo "- This could indicate the limit has changed or uploads were handled differently" >> $GITHUB_STEP_SUMMARY + echo "- Check the workflow logs for details" >> $GITHUB_STEP_SUMMARY + fi + echo "" >> $GITHUB_STEP_SUMMARY + + echo "## Test 2: Upload Single Zip Archive" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Result:** ✅ Success" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- 📦 Archive contains all 501 files" >> $GITHUB_STEP_SUMMARY + echo "- 🎯 Artifacts used: **1** (well within the 500 limit)" >> $GITHUB_STEP_SUMMARY + echo "- 💾 Single zip file uploaded successfully" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + echo "---" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "## 💡 Conclusion & Best Practice" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "When you need to upload more than 500 files:" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "1. ✅ **Combine files** into a single archive (zip, tar.gz, etc.)" >> $GITHUB_STEP_SUMMARY + echo "2. ✅ **Upload the archive** as a single artifact" >> $GITHUB_STEP_SUMMARY + echo "3. ✅ **Bypass the limit** while preserving all files" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "This approach is more efficient and works around the 500 artifact limitation." >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "📚 **Reference:** [upload-artifact documentation](https://github.com/actions/upload-artifact?tab=readme-ov-file#breaking-changes)" >> $GITHUB_STEP_SUMMARY