-
Notifications
You must be signed in to change notification settings - Fork 12
(DRAFT-RUN) HYPERFLEET-1024 - feat: automate #37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
36402d2
b79ec7d
6cb4bd2
1a50632
c2c02c5
ff27042
f82792c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| name: CI | ||
|
|
||
| on: | ||
| pull_request: | ||
| push: | ||
| branches: | ||
| - main | ||
|
|
||
| jobs: | ||
| validate: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v6 | ||
| with: | ||
| node-version: '20' | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci | ||
|
|
||
| - name: Install TypeSpec compiler | ||
| run: npm install -g @typespec/compiler@1.11 | ||
|
|
||
| - name: Install Spectral CLI | ||
| run: npm install -g @stoplight/spectral-cli | ||
|
|
||
| - name: Build all schemas | ||
| run: | | ||
| ./build-schema.sh core | ||
| ./build-schema.sh core --swagger | ||
| ./build-schema.sh gcp | ||
| ./build-schema.sh gcp --swagger | ||
|
|
||
| - name: Check schema consistency | ||
| run: | | ||
| if ! git diff --exit-code schemas/; then | ||
| echo "Committed schemas are out of sync with TypeSpec sources." | ||
| echo "Run './build-schema.sh core --swagger && ./build-schema.sh gcp --swagger' and commit the results." | ||
| exit 1 | ||
| fi | ||
|
|
||
| - name: Lint OpenAPI schemas | ||
| run: | | ||
| spectral lint schemas/core/openapi.yaml schemas/gcp/openapi.yaml --format github-actions | ||
|
|
||
| - name: Check version bump | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| CURRENT=$(grep -oP '(?<=version: ")[^"]+' main.tsp) | ||
| LATEST=$(gh release list --limit 1 --json tagName --jq '.[0].tagName' 2>/dev/null | sed 's/^v//' || echo "") | ||
| if [ -z "$LATEST" ]; then | ||
| echo "No previous releases found — version check skipped" | ||
| exit 0 | ||
| fi | ||
|
Comment on lines
+57
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Check if the workflow file exists and examine lines 57-61
if [ -f .github/workflows/ci.yml ]; then
echo "=== File exists. Checking lines 57-61 ==="
sed -n '57,61p' .github/workflows/ci.yml
echo ""
echo "=== Full context (lines 50-70) ==="
sed -n '50,70p' .github/workflows/ci.yml
else
echo ".github/workflows/ci.yml does not exist"
# Try to find any CI workflow file
find . -name "ci.yml" -o -name "ci.yaml" 2>/dev/null | head -10
fiRepository: openshift-hyperfleet/hyperfleet-api-spec Length of output: 1201 Fail closed when release lookup fails in the version gate. At line 57, errors from the release lookup are suppressed with Suggested fix- LATEST=$(gh release list --limit 1 --json tagName --jq '.[0].tagName' 2>/dev/null | sed 's/^v//' || echo "")
- if [ -z "$LATEST" ]; then
+ if ! LATEST_RAW=$(gh release list --limit 1 --json tagName --jq '.[0].tagName' 2>/dev/null); then
+ echo "Failed to query latest release tag"
+ exit 1
+ fi
+ LATEST="${LATEST_RAW#v}"
+ if [ -z "$LATEST" ]; then
echo "No previous releases found — version check skipped"
exit 0
fi🤖 Prompt for AI Agents |
||
| if [ "$CURRENT" = "$LATEST" ]; then | ||
| echo "Version '$CURRENT' matches latest release tag 'v$LATEST' — bump the version in main.tsp before merging." | ||
| exit 1 | ||
| fi | ||
| echo "Version bump OK: $LATEST → $CURRENT" | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,50 +2,87 @@ name: Create Release | |||||||||||||||||||||
|
|
||||||||||||||||||||||
| on: | ||||||||||||||||||||||
| push: | ||||||||||||||||||||||
| tags: | ||||||||||||||||||||||
| - 'v*' | ||||||||||||||||||||||
| branches: | ||||||||||||||||||||||
| - main-test | ||||||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||||||
|
Comment on lines
4
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Trigger branch The PR is targeting Proposed fix push:
branches:
- - main-test
+ - main
workflow_dispatch:📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||
| release: | ||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||
| contents: write | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| steps: | ||||||||||||||||||||||
| - name: Checkout code | ||||||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||||||
| uses: actions/checkout@v6 | ||||||||||||||||||||||
| with: | ||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - name: Setup Node.js | ||||||||||||||||||||||
| uses: actions/setup-node@v4 | ||||||||||||||||||||||
| uses: actions/setup-node@v6 | ||||||||||||||||||||||
| with: | ||||||||||||||||||||||
| node-version: '20' | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - name: Install dependencies | ||||||||||||||||||||||
| run: npm install | ||||||||||||||||||||||
| run: npm ci | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - name: Install tsp | ||||||||||||||||||||||
| run: npm install -g @typespec/compiler@1.6 | ||||||||||||||||||||||
| - name: Install TypeSpec compiler | ||||||||||||||||||||||
| run: npm install -g @typespec/compiler@1.11 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - name: Build Core schema | ||||||||||||||||||||||
| run: ./build-schema.sh core | ||||||||||||||||||||||
| - name: Extract version | ||||||||||||||||||||||
| id: version | ||||||||||||||||||||||
| run: | | ||||||||||||||||||||||
| VERSION=$(grep -oP '(?<=version: ")[^"]+' main.tsp) | ||||||||||||||||||||||
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | ||||||||||||||||||||||
| echo "tag=v$VERSION" >> "$GITHUB_OUTPUT" | ||||||||||||||||||||||
|
Comment on lines
+35
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validate extracted release version before deriving the tag. At Line 34, the workflow assumes extraction always succeeds. If it fails, you can emit Proposed fix- VERSION=$(grep -oP '(?<=version: ")[^"]+' main.tsp)
+ VERSION=$(sed -nE 's/.*version:[[:space:]]*"([^"]+)".*/\1/p' main.tsp | head -n1)
+ if [ -z "$VERSION" ]; then
+ echo "Failed to extract version from main.tsp"
+ exit 1
+ fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - name: Build GCP schema | ||||||||||||||||||||||
| run: ./build-schema.sh gcp | ||||||||||||||||||||||
| - name: Check if release already exists | ||||||||||||||||||||||
| id: check_tag | ||||||||||||||||||||||
| run: | | ||||||||||||||||||||||
| git fetch --tags | ||||||||||||||||||||||
| if git rev-parse "${{ steps.version.outputs.tag }}" >/dev/null 2>&1; then | ||||||||||||||||||||||
| echo "Tag ${{ steps.version.outputs.tag }} already exists — skipping release" | ||||||||||||||||||||||
| echo "skip=true" >> "$GITHUB_OUTPUT" | ||||||||||||||||||||||
| else | ||||||||||||||||||||||
| echo "skip=false" >> "$GITHUB_OUTPUT" | ||||||||||||||||||||||
| fi | ||||||||||||||||||||||
|
Comment on lines
+39
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: cat -n .github/workflows/release.yml | sed -n '30,85p'Repository: openshift-hyperfleet/hyperfleet-api-spec Length of output: 2524 Tag-based skip logic prevents release recovery after partial failures. At line 42, the workflow checks tag existence using Suggested fix- - name: Check if release already exists
- id: check_tag
+ - name: Check if release already exists
+ id: check_release
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
- git fetch --tags
- if git rev-parse "${{ steps.version.outputs.tag }}" >/dev/null 2>&1; then
- echo "Tag ${{ steps.version.outputs.tag }} already exists — skipping release"
+ if gh release view "${{ steps.version.outputs.tag }}" >/dev/null 2>&1; then
+ echo "Release ${{ steps.version.outputs.tag }} already exists — skipping release"
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- - name: Build all schemas
- if: steps.check_tag.outputs.skip == 'false'
+ - name: Build all schemas
+ if: steps.check_release.outputs.skip == 'false'
- - name: Prepare release assets
- if: steps.check_tag.outputs.skip == 'false'
+ - name: Prepare release assets
+ if: steps.check_release.outputs.skip == 'false'
- - name: Create release tag
- if: steps.check_tag.outputs.skip == 'false'
+ - name: Create release tag
+ if: steps.check_release.outputs.skip == 'false'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- git tag -a "${{ steps.version.outputs.tag }}" -m "Release ${{ steps.version.outputs.tag }}"
- git push origin "${{ steps.version.outputs.tag }}"
+ git fetch --tags
+ if git rev-parse "${{ steps.version.outputs.tag }}" >/dev/null 2>&1; then
+ echo "Tag already exists; continuing to release creation."
+ else
+ git tag -a "${{ steps.version.outputs.tag }}" -m "Release ${{ steps.version.outputs.tag }}"
+ git push origin "${{ steps.version.outputs.tag }}"
+ fi
- - name: Create GitHub Release
- if: steps.check_tag.outputs.skip == 'false'
+ - name: Create GitHub Release
+ if: steps.check_release.outputs.skip == 'false'🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - name: Build all schemas | ||||||||||||||||||||||
| if: steps.check_tag.outputs.skip == 'false' | ||||||||||||||||||||||
| run: | | ||||||||||||||||||||||
| ./build-schema.sh core | ||||||||||||||||||||||
| ./build-schema.sh core --swagger | ||||||||||||||||||||||
| ./build-schema.sh gcp | ||||||||||||||||||||||
| ./build-schema.sh gcp --swagger | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - name: Prepare release assets | ||||||||||||||||||||||
| if: steps.check_tag.outputs.skip == 'false' | ||||||||||||||||||||||
| run: | | ||||||||||||||||||||||
| cp schemas/core/openapi.yaml core-openapi.yaml | ||||||||||||||||||||||
| cp schemas/core/swagger.yaml core-swagger.yaml | ||||||||||||||||||||||
| cp schemas/gcp/openapi.yaml gcp-openapi.yaml | ||||||||||||||||||||||
| cp schemas/gcp/swagger.yaml gcp-swagger.yaml | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - name: Create release tag | ||||||||||||||||||||||
| if: steps.check_tag.outputs.skip == 'false' | ||||||||||||||||||||||
| run: | | ||||||||||||||||||||||
| git config user.name "github-actions[bot]" | ||||||||||||||||||||||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||||||||||||||||||||||
| git tag -a "${{ steps.version.outputs.tag }}" -m "Release ${{ steps.version.outputs.tag }}" | ||||||||||||||||||||||
| git push origin "${{ steps.version.outputs.tag }}" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - name: Create Release | ||||||||||||||||||||||
| - name: Create GitHub Release | ||||||||||||||||||||||
| if: steps.check_tag.outputs.skip == 'false' | ||||||||||||||||||||||
| uses: softprops/action-gh-release@v2 | ||||||||||||||||||||||
| with: | ||||||||||||||||||||||
| tag_name: ${{ steps.version.outputs.tag }} | ||||||||||||||||||||||
| generate_release_notes: true | ||||||||||||||||||||||
| draft: false | ||||||||||||||||||||||
| prerelease: false | ||||||||||||||||||||||
| files: | | ||||||||||||||||||||||
| core-openapi.yaml | ||||||||||||||||||||||
| core-swagger.yaml | ||||||||||||||||||||||
| gcp-openapi.yaml | ||||||||||||||||||||||
| draft: false | ||||||||||||||||||||||
| prerelease: false | ||||||||||||||||||||||
| generate_release_notes: true | ||||||||||||||||||||||
| gcp-swagger.yaml | ||||||||||||||||||||||
| env: | ||||||||||||||||||||||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| extends: ["spectral:oas"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| module github.com/openshift-hyperfleet/hyperfleet-api-spec | ||
|
|
||
| go 1.23 |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // Package schemas exposes the generated HyperFleet OpenAPI schema files as an embedded filesystem. | ||
| // Consumers can import this package to access versioned schema content without vendoring local copies. | ||
| // | ||
| // Usage: | ||
| // | ||
| // import specschemas "github.com/openshift-hyperfleet/hyperfleet-api-spec/schemas" | ||
| // | ||
| // data, err := specschemas.FS.ReadFile("gcp/openapi.yaml") | ||
| package schemas | ||
|
|
||
| import "embed" | ||
|
|
||
| //go:embed core/openapi.yaml core/swagger.yaml gcp/openapi.yaml gcp/swagger.yaml | ||
| var FS embed.FS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Harden version extraction before enforcing the bump gate.
At Line 52, the parsed version is not validated. If parsing returns empty/unexpected output, the version-check logic can produce false passes. Fail fast when
CURRENTis empty.Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents