name: actions-importer-issue-ops on: issue_comment: types: [created] permissions: contents: read issues: write defaults: run: shell: bash env: GITHUB_INSTANCE_URL: ${{ secrets.GH_INSTANCE_URL || 'https://github.com' }} GITHUB_ACCESS_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }} JENKINS_INSTANCE_URL: ${{ secrets.JENKINS_INSTANCE_URL }} JENKINS_USERNAME: ${{ secrets.jenkins_username }} JENKINS_ACCESS_TOKEN: ${{ secrets.jenkins_access_token }} JENKINSFILE_ACCESS_TOKEN: ${{ secrets.jenkinsfile_access_token }} AZURE_DEVOPS_ACCESS_TOKEN: ${{ secrets.azure_devops_access_token }} TRAVIS_CI_ACCESS_TOKEN: ${{ secrets.travis_ci_access_token }} TRAVIS_CI_SOURCE_GITHUB_ACCESS_TOKEN: ${{ secrets.travis_ci_source_github_access_token }} GITLAB_ACCESS_TOKEN: ${{ secrets.gitlab_access_token }} GITLAB_INSTANCE_URL: ${{ secrets.gitlab_instance_url || 'https://gitlab.com' }} CIRCLE_CI_ACCESS_TOKEN: ${{ secrets.circle_ci_access_token }} CIRCLE_CI_SOURCE_GITHUB_ACCESS_TOKEN: ${{ secrets.circle_ci_source_github_access_token }} BAMBOO_ACCESS_TOKEN: ${{ secrets.bamboo_access_token }} BAMBOO_INSTANCE_URL: ${{ secrets.bamboo_instance_url }} BITBUCKET_ACCESS_TOKEN: ${{ secrets.bitbucket_access_token }} jobs: execute-actions-importer: runs-on: ubuntu-latest outputs: command: ${{ steps.prepare.outputs.command }} log-filename: ${{ steps.logs.outputs.filename }} steps: - name: Install GitHub Actions Importer run: | gh actions-importer version || gh extension install github/gh-actions-importer gh actions-importer update env: GH_TOKEN: ${{ github.token }} - uses: actions/github-script@v7 if: always() with: script: | github.rest.issues.addLabels({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, labels: ['actions-importer-running'] }) - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 # ImageOs must be configured to match the OS of the runner when using self-hosted runners. # env: # ImageOS: ubuntu22 - name: Install Dependencies run: bundle install env: BUNDLE_WITHOUT: development - name: Prepare arguments id: prepare env: ISSUE_BODY: ${{ github.event.issue.body }} COMMENT_BODY: ${{ github.event.comment.body }} LABELS: ${{ toJSON(github.event.issue.labels.*.name) }} run: | ./bin/parse_issue "$ISSUE_BODY" "$COMMENT_BODY" "$LABELS" - name: Validate arguments run: | if [ -z "${{ steps.prepare.outputs.provider }}" ]; then echo "Unable to determine provider" exit 1 elif [ -z "${{ steps.prepare.outputs.command }}" ]; then echo "Unable to determine command" exit 1 fi - name: execute actions-importer run: | gh actions-importer ${{ steps.prepare.outputs.command }} ${{ steps.prepare.outputs.provider }} \ ${{ steps.prepare.outputs.args }} \ --output-dir output - uses: actions/upload-artifact@v4 if: always() with: path: output/ name: output - if: always() id: logs run: | path=$(ls output/log/*.log | head -1) filename=$(basename "$path") echo "LOG_FILE_PATH=$path" >> $GITHUB_ENV echo "filename=$filename" >> $GITHUB_OUTPUT - uses: actions/upload-artifact@v4 if: always() with: path: ${{ env.LOG_FILE_PATH }} name: logs audit: runs-on: ubuntu-latest if: needs.execute-actions-importer.outputs.command == 'audit' needs: execute-actions-importer steps: - uses: actions/download-artifact@v4 if: always() with: name: output - uses: actions/github-script@v7 with: script: | const fs = require('fs') const summaryText = fs.readFileSync("./audit_summary.md", "utf8") const MAX_LENGTH = 64000 const artifactUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${process.env.GITHUB_RUN_ID}` const body = `Audit successfully completed :rocket: Download full results [here](${artifactUrl})
Audit summary :point_down: \`\`\` ${summaryText.substring(0, Math.min(summaryText.length, MAX_LENGTH))} \`\`\`
` await github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body }) dry-run: runs-on: ubuntu-latest if: needs.execute-actions-importer.outputs.command == 'dry-run' needs: execute-actions-importer steps: - uses: actions/download-artifact@v4 if: always() with: name: output - uses: actions/github-script@v7 with: script: | const fs = require('fs') const directory = "${{ github.workspace }}/" const globber = await glob.create(`${directory}**/*.yml`) const MAX_LENGTH = 64000 let currentLength = 0 const workflows = [] for await (const file of globber.globGenerator()) { const content = fs.readFileSync(file, 'utf8') const data = [ "
", ` ${file.substring(directory.length)}`, "", "```yaml", content, "```", "
", "" ] for (const element of data) { currentLength += element.length; } if (currentLength > MAX_LENGTH){ break } workflows.push(...data) } const body = `Dry run was successful :boom: Transformed workflows: ${workflows.join("\n")} ` await github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body }) migrate: runs-on: ubuntu-latest if: needs.execute-actions-importer.outputs.command == 'migrate' needs: execute-actions-importer steps: - uses: actions/download-artifact@v4 if: always() with: name: logs - id: pull-request-url run: | pullRequest=$(grep "${{ env.pullRequestPattern }}" ${{ needs.execute-actions-importer.outputs.log-filename }} | sed -rn "s/^.*${{ env.pullRequestPattern }}'(.+)'.*$/\1/p") echo $pullRequest echo "output=$pullRequest" >> $GITHUB_OUTPUT env: pullRequestPattern: "Pull request: " - uses: actions/github-script@v7 env: PULL_REQUEST_URL: "${{ steps.pull-request-url.outputs.output }}" with: script: | const body = `Migration was successful :sparkles: Continue to the [pull request](${process.env.PULL_REQUEST_URL}) to complete the migration. ` try { await github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body }) } catch(e) { console.log(e) } cleanup: runs-on: ubuntu-latest needs: [execute-actions-importer, audit, migrate, dry-run] if: always() steps: - uses: actions/download-artifact@v4 if: always() && needs.execute-actions-importer.result == 'failure' with: name: logs - uses: actions/github-script@v7 if: always() && needs.execute-actions-importer.result == 'failure' with: script: | const fs = require('fs') const MAX_LENGTH = 64000 const logData = fs.readFileSync("${{ needs.execute-actions-importer.outputs.log-filename }}", "utf8") const body = `Something went wrong. Please check the logs for more information.
Logs :point_down: \`\`\` ${logData.substring(0, Math.min(logData.length, MAX_LENGTH))} \`\`\`
` await github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body }) - uses: actions/github-script@v7 if: always() with: script: | await github.rest.issues.removeLabel({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, name: 'actions-importer-running' });