Skip to content
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

airbyte-ci: add format commands #31831

Merged
merged 147 commits into from
Nov 14, 2023
Merged

Conversation

erohmensing
Copy link
Contributor

@erohmensing erohmensing commented Oct 25, 2023

What

How

  • New airbyte-ci format fix and airbyte-ci format check subgroups
  • New commands which run (daggerized):
    • Java + sql: spotless, via gradle, in a JDK container
    • Yaml/Json: prettier, not via gradle, in a node container
    • License checking: License checking via a new tool, addlicense, in a go container (also no longer through gradle)
    • Python: black and isort, in a python container, no longer via gradle
  • Remove everything possible that doesn't touch java code out of gradle
  • Remove formatting from connector testing
  • Remove format command from gradle and the gradle check workflow - format checking and formatting should only happen via ci (gradle does other checking still)

Usage

General workflow:
0. Dev pushes a PR

  1. If they didn't format something correctly, the workflow fails
  2. The user sees that they should run the formatter
  3. They run the formatter and commit it
  4. Success

Other ways we can increase the ease of formatting:

  • Instructions on how to set up various IDEs (intellij, vscode) with the new top-level pyproject.toml files to autoformat
  • Pre-commit or pre-push hooks (i'm partial to the latter) that devs can opt into

Todo

  • This new check should be required, even before octavia approvington. It takes ~3 mins to run. Making sure that each PR is formatted is the key to keeping master from getting into a weird state where formatting seems to "ghost format" code that you didn't touch. E.g. this should feel similar to the current workflow in platform

Recommended reading order

  1. x.java
  2. y.python

🚨 User Impact 🚨

  • New functionality in airbyte-ci :)
  • No more autoformatting commits on PRs
  • Users may see formatting fail in CI and need to fix it locally (similar to in the platform repo)

@vercel
Copy link

vercel bot commented Oct 25, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Ignored Deployment
Name Status Preview Comments Updated (UTC)
airbyte-docs ⬜️ Ignored (Inspect) Visit Preview Nov 13, 2023 9:14am

Copy link
Contributor Author

erohmensing commented Oct 25, 2023

Comment on lines 23 to 75
async def format_java(fix: bool) -> bool:
logger = logging.getLogger("format")
if fix:
gradle_command = ["./gradlew", "spotlessApply"]
else:
gradle_command = ["./gradlew", "spotlessCheck", "--scan"]

async with dagger.Connection(dagger.Config(log_output=sys.stderr)) as dagger_client:
try:
format_container = await (
dagger_client.container()
.from_("openjdk:17.0.1-jdk-slim")
.with_exec(
sh_dash_c(
[
"apt-get update",
"apt-get install -y bash",
]
)
)
.with_mounted_directory(
"/src",
dagger_client.host().directory(
".",
include=[
"**/*.java",
"**/*.sql",
"**/*.gradle",
"gradlew",
"gradlew.bat",
"gradle",
"**/deps.toml",
"**/gradle.properties",
"**/version.properties",
"tools/gradle/codestyle/java-google-style.xml",
"tools/gradle/codestyle/sql-dbeaver.properties",
],
exclude=DEFAULT_FORMAT_IGNORE_LIST,
),
)
.with_workdir(f"/src")
.with_exec(gradle_command)
)

await format_container
if fix:
await format_container.directory("/src").export(".")

return True
except dagger.ExecError as e:
logger.error("Format failed")
logger.error(e.stderr)
return False
Copy link
Contributor

@alafanechere alafanechere Oct 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 This is what I meant in your demo when I asked "are you using the Python GradleTask class" (I know it's utterly confusing when said orally 🤣 ).
Re-using this class (or just its methods) would make sure we have a standard way of running the gradle commands in dagger. We recently improved it to make sure subsequent runs benefit from caching.

I realize that with Lazy subcommand we're stepping away from the Step and pipeline paradigm which happens in the connector subgroup.
I find this new approach elegant, nevertheless, I'd appreciate code reuse.
Feel free to split this class up to not make all its internal logic depend on the Step one and pick the things you need from it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh this one! true! Great point, I'll take a look :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave this a try - it was really hard without knowing what's really going on in here. The current code although its a "gradle task" command is highly configured to handle gradle commands in connector containers.

I personally would feel uncomfortable messing around with this too much myself. If you want to stack off of this to split up the gradleTask into a gradle base container in which i can run gradle commands (not just connector gradle commands), that'd be very welcome!

Here's the commit where I took a crack; it was also hard with the PipelineContext etc,:
a22a14b

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a sign that some further refactoring is required for this change to land properly. I'm not surprised that the PipelineContext and friends get in the way, and that they would need to be changed at some point. Perhaps the time has come, though that would be outside the scope of this PR.

Comment on lines 41 to 49
.from_("node:18.18.0-slim")
.with_exec(
sh_dash_c(
[
"apt-get update",
"apt-get install -y bash",
]
)
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be declared a dagger/action/?module and we'd call: with_node(dagger_client, node_version)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dumb question - that would be a container, not an action, right?

I was tripped up by most containers in dagger actions taking in pipelineContexts, not dagger_clients.

or is it dagger.container().with_go? 🤔

Without the apt-get updating i've removed, that method would just be

return container.from_(NODE_IMAGE) I think

try:
license_container = await (
dagger_client.container()
.from_("golang:1.17")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as for node: a with_go(dagger_client, go_version) action function call would be nice

@erohmensing erohmensing changed the base branch from master to bnchrch/simple-pipeline-context October 31, 2023 17:50
Copy link
Contributor

@postamar postamar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did another pass. LGTM

Copy link
Contributor

@alafanechere alafanechere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

Copy link
Contributor

Before Merging a Connector Pull Request

Wow! What a great pull request you have here! 🎉

To merge this PR, ensure the following has been done/considered for each connector added or updated:

  • PR name follows PR naming conventions
  • Breaking changes are considered. If a Breaking Change is being introduced, ensure an Airbyte engineer has created a Breaking Change Plan.
  • Connector version has been incremented in the Dockerfile and metadata.yaml according to our Semantic Versioning for Connectors guidelines
  • You've updated the connector's metadata.yaml file any other relevant changes, including a breakingChanges entry for major version bumps. See metadata.yaml docs
  • Secrets in the connector's spec are annotated with airbyte_secret
  • All documentation files are up to date. (README.md, bootstrap.md, docs.md, etc...)
  • Changelog updated in docs/integrations/<source or destination>/<name>.md with an entry for the new version. See changelog example
  • Migration guide updated in docs/integrations/<source or destination>/<name>-migrations.md with an entry for the new version, if the version is a breaking change. See migration guide example
  • If set, you've ensured the icon is present in the platform-internal repo. (Docs)

If the checklist is complete, but the CI check is failing,

  1. Check for hidden checklists in your PR description

  2. Toggle the github label checklist-action-run on/off to re-run the checklist CI.

@alafanechere
Copy link
Contributor

/approve-and-merge reason="bypass connectors tests - formatting changes only"

@octavia-approvington
Copy link
Contributor

Enough! Let's do this
goooooo!

@octavia-approvington octavia-approvington merged commit ac3eb28 into master Nov 14, 2023
34 of 37 checks passed
@octavia-approvington octavia-approvington deleted the ella/format-commands branch November 14, 2023 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

airbyte-ci: top level formatting replaces connector-level formatting and gradle format ci job
8 participants