fix(aws-api-mcp-server): validate origin/host headers #10422
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: TypeScript | |
| on: | |
| push: | |
| pull_request: | |
| permissions: {} | |
| jobs: | |
| detect-packages: | |
| permissions: | |
| contents: read | |
| runs-on: ubuntu-latest | |
| outputs: | |
| packages: ${{ steps.find-packages.outputs.packages }} | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| - name: Find JS packages | |
| id: find-packages | |
| working-directory: src | |
| run: | | |
| PACKAGES=$(find . -name package.json -not -path "*/node_modules/*" -exec dirname {} \; | sed 's/^\.\///' | jq -R -s -c 'split("\n")[:-1]') | |
| echo "packages=$PACKAGES" >> $GITHUB_OUTPUT | |
| build: | |
| needs: [detect-packages] | |
| if: ${{ needs.detect-packages.outputs.packages != '[]' && needs.detect-packages.outputs.packages != '' }} | |
| strategy: | |
| matrix: | |
| package: ${{ fromJson(needs.detect-packages.outputs.packages) }} | |
| name: Build ${{ matrix.package }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 | |
| with: | |
| node-version-file: "src/${{ matrix.package }}/.node-version" | |
| cache: npm | |
| - name: Install dependencies | |
| working-directory: src/${{ matrix.package }} | |
| run: npm ci | |
| - name: Build package | |
| working-directory: src/${{ matrix.package }} | |
| run: npm run build | |
| - name: Upload Distribution | |
| uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 | |
| with: | |
| name: dist-${{ matrix.package }} | |
| path: src/${{ matrix.package }}/dist/ | |
| - name: Generate Software Bill of Materials (SBOM) | |
| run: | |
| npx @cyclonedx/cyclonedx-npm --gather-license-texts --mc-type library --output-format XML > src/${{ matrix.package }}/sbom.cyclondx.xml | |
| - name: Set up Python | |
| uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 | |
| with: | |
| python-version: "3.x" | |
| - name: Display SBOM | |
| run: | | |
| cat <<EOT | | |
| import re | |
| import xml.etree.ElementTree as ET | |
| import importlib.metadata as metadata | |
| def parse_bom(xml_file): | |
| # Parse the XML file | |
| tree = ET.parse(xml_file) | |
| root = tree.getroot() | |
| # Get the latest namespace | |
| find_namespace = re.match(r'\{.*\}', root.tag) | |
| # Define the namespace | |
| ns = {'cyclonedx': find_namespace.group(0)[1:-1] if find_namespace else 'http://cyclonedx.org/schema/bom/1.5'} | |
| # Extract components | |
| components = [] | |
| for component in root.findall('.//cyclonedx:component', ns): | |
| comp_info = {} | |
| # Get name, version, description, and purl | |
| comp_info['name'] = component.find('cyclonedx:name', ns).text | |
| comp_info['version'] = component.find('cyclonedx:version', ns).text | |
| comp_info['description'] = component.find('cyclonedx:description', ns).text if component.find('cyclonedx:description', ns) is not None else "No description" | |
| comp_info['purl'] = component.find('cyclonedx:purl', ns).text if component.find('cyclonedx:purl', ns) is not None else "No PURL" | |
| # Get licenses | |
| licenses = component.findall('.//cyclonedx:license/cyclonedx:id', ns) | |
| if licenses: | |
| comp_info['licenses'] = [license.text for license in licenses] | |
| else: | |
| comp_info['licenses'] = ["No licenses"] | |
| # Extract additional information (copyright, etc.) | |
| copyright_info = extract_copyright_from_metadata(comp_info['name']) | |
| comp_info['copyright'] = copyright_info if copyright_info else "No copyright information" | |
| components.append(comp_info) | |
| return components | |
| def extract_copyright_from_metadata(package_name): | |
| try: | |
| # Use importlib.metadata to retrieve metadata from the installed package | |
| dist = metadata.distribution(package_name) | |
| metadata_info = dist.metadata | |
| # Extract relevant metadata | |
| copyright_info = [] | |
| author = metadata_info.get('Author') | |
| author_email = metadata_info.get('Author-email') | |
| license_info = metadata_info.get('License') | |
| if author: | |
| copyright_info.append(f"Author: {author}") | |
| if author_email: | |
| copyright_info.append(f"Author Email: {author_email}") | |
| if license_info: | |
| copyright_info.append(f"License: {license_info}") | |
| # Check for classifiers or any extra metadata fields | |
| if 'Classifier' in metadata_info: | |
| for classifier in metadata_info.get_all('Classifier'): | |
| if 'copyright' in classifier.lower(): | |
| copyright_info.append(classifier) | |
| return ', '.join(copyright_info) if copyright_info else None | |
| except metadata.PackageNotFoundError: | |
| return None | |
| def main(): | |
| bom_file = 'bom.xml' # Replace with your BOM file path | |
| components = parse_bom(bom_file) | |
| for component in components: | |
| print(f"Name: {component['name']}") | |
| print(f"Version: {component['version']}") | |
| print(f"Description: {component['description']}") | |
| print(f"PURL: {component['purl']}") | |
| print(f"Licenses: {', '.join(component['licenses'])}") | |
| print(f"Copyright: {component['copyright']}") | |
| print("-" * 40) | |
| if __name__ == "__main__": | |
| main() | |
| EOT | |
| python - | |
| - name: Upload Software Bill of Materials | |
| uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 | |
| with: | |
| name: sbom-${{ matrix.package }} | |
| path: src/${{ matrix.package }}/sbom.cyclondx.xml |